suite.addTestSuite(CovarianceTests.class); | suite.addTestSuite(CovarianceTests.class); | ||||
suite.addTestSuite(Enums.class); | suite.addTestSuite(Enums.class); | ||||
suite.addTestSuite(Annotations.class); | suite.addTestSuite(Annotations.class); | ||||
suite.addTestSuite(Varargs.class); | |||||
//$JUnit-END$ | //$JUnit-END$ | ||||
return suite; | return suite; | ||||
} | } |
private static final boolean verbose = false; | private static final boolean verbose = false; | ||||
protected File baseDir; | protected File baseDir; | ||||
protected CompilationResult binaryWeave(String inpath,String insource,int expErrors,int expWarnings) { | |||||
return binaryWeave(inpath,insource,expErrors,expWarnings,false); | |||||
} | |||||
protected CompilationResult binaryWeave(String inpath, String insource,int expErrors,int expWarnings) { | |||||
String[] args = new String[] {"-inpath",inpath,insource,"-showWeaveInfo","-proceedOnError"}; | |||||
protected CompilationResult binaryWeave(String inpath, String insource,int expErrors,int expWarnings,boolean xlinterror) { | |||||
String[] args = null; | |||||
if (xlinterror) { | |||||
args = new String[] {"-inpath",inpath,insource,"-showWeaveInfo","-proceedOnError","-Xlint:warning"}; | |||||
} else { | |||||
args = new String[] {"-inpath",inpath,insource,"-showWeaveInfo","-proceedOnError"}; | |||||
} | |||||
CompilationResult result = ajc(baseDir,args); | CompilationResult result = ajc(baseDir,args); | ||||
if (verbose || result.hasErrorMessages()) System.out.println(result); | if (verbose || result.hasErrorMessages()) System.out.println(result); | ||||
assertTrue("Expected "+expErrors+" errors but got "+result.getErrorMessages().size()+":\n"+ | assertTrue("Expected "+expErrors+" errors but got "+result.getErrorMessages().size()+":\n"+ |
/******************************************************************************* | |||||
* Copyright (c) 2004 IBM | |||||
* All rights reserved. This program and the accompanying materials | |||||
* are made available under the terms of the Common Public License v1.0 | |||||
* which accompanies this distribution, and is available at | |||||
* http://www.eclipse.org/legal/cpl-v10.html | |||||
* | |||||
* Contributors: | |||||
* Andy Clement - initial API and implementation | |||||
*******************************************************************************/ | |||||
package org.aspectj.systemtest.ajc150; | |||||
import java.io.File; | |||||
import org.aspectj.bridge.IMessage; | |||||
import org.aspectj.tools.ajc.CompilationResult; | |||||
/** | |||||
* Varargs, the rules/tests: | |||||
* | |||||
* 1. cannot match on a varargs method by using 'Object[]' in your signature, | |||||
* this affects call/execution/initialization/withincode | |||||
*/ | |||||
public class Varargs extends TestUtils { | |||||
protected void setUp() throws Exception { | |||||
super.setUp(); | |||||
baseDir = new File("../tests/java5/varargs"); | |||||
} | |||||
// check when signature is from a call PCD | |||||
// should get message: | |||||
// "an array type as the last parameter in a signature does not match on the varargs declared method: <blah>" | |||||
public void test001_cantMatchVarargsWithObjectArray_callPCD() { | |||||
CompilationResult cR = binaryWeave("testcode.jar","VarargsAspect01.aj",0,3,true); | |||||
assertTrue("Did not get expected message about a varargs mismatch, instead got: "+cR.getWarningMessages(), | |||||
((IMessage)cR.getWarningMessages().get(0)).toString().indexOf("varargs declared method")!=-1); | |||||
verifyWeavingMessagesOutput(cR,new String[]{}); | |||||
} | |||||
// check when signature is from an execution PCD | |||||
public void test002_cantMatchVarargsWithObjectArray_execPCD() { | |||||
CompilationResult cR = binaryWeave("testcode.jar","VarargsAspect02.aj",0,1,true); | |||||
assertTrue("Did not get expected message about a varargs mismatch, instead got: "+cR.getWarningMessages(), | |||||
((IMessage)cR.getWarningMessages().get(0)).toString().indexOf("varargs declared method")!=-1); | |||||
verifyWeavingMessagesOutput(cR,new String[]{}); | |||||
} | |||||
// check when signature is from an initialization PCD | |||||
public void test003_cantMatchVarargsWithObjectArray_initPCD() { | |||||
CompilationResult cR = binaryWeave("testcode.jar","VarargsAspect03.aj",0,1,true); | |||||
assertTrue("Did not get expected message about a varags mismatch, instead got: "+cR.getWarningMessages(), | |||||
((IMessage)cR.getWarningMessages().get(0)).toString().indexOf("varargs declared method")!=-1); | |||||
verifyWeavingMessagesOutput(cR,new String[]{}); | |||||
} | |||||
// check when signature is from an withincode PCD | |||||
public void test003_cantMatchVarargsWithObjectArray_withincodePCD() { | |||||
CompilationResult cR = binaryWeave("testcode.jar","VarargsAspect04.aj",0,1,true); | |||||
assertTrue("Did not get expected message about a varags mismatch, instead got: "+cR.getWarningMessages(), | |||||
((IMessage)cR.getWarningMessages().get(0)).toString().indexOf("varargs declared method")!=-1); | |||||
verifyWeavingMessagesOutput(cR,new String[]{}); | |||||
} | |||||
} |
X Bridge Methods (Ignore them completely - they provide no join points) | X Bridge Methods (Ignore them completely - they provide no join points) | ||||
X Covariance (Properly support covariance) | X Covariance (Properly support covariance) | ||||
o Varargs (Don't allow Object[] to match a varargs method) | |||||
o Autoboxing ( | |||||
o -source 1.5 (So we can change our behavior, e.g. autoboxing) | |||||
o LocalVarTypeTable (Manipulate it the same as we do the LocalVariableTable) | |||||
X Annotations (No ITDs allowed) | X Annotations (No ITDs allowed) | ||||
X Enums (No ITDs allowed) | X Enums (No ITDs allowed) | ||||
X Varargs (Don't allow Object[] to match a varargs method) | |||||
o Autoboxing | |||||
o -source 1.5 (So we can change our behavior, e.g. autoboxing) | |||||
o LocalVarTypeTable (Manipulate it the same as we do the LocalVariableTable) | |||||
o Annotation (No DECPs allowed) | o Annotation (No DECPs allowed) | ||||
o Enums (No DECPs allowed) | o Enums (No DECPs allowed) | ||||
=== | |||||
Things not done: | |||||
Marked with XXXAJ5 - currently tagging things like: | |||||
- No covariance support for dynamic pointcut matching, need to dup declaringTypeMatch() changes for cov support | |||||
=== | === | ||||
Things we ought to do: | Things we ought to do: | ||||
- Lift binary decp restriction | - Lift binary decp restriction | ||||
- ResolvedTypeMunger - switch on remembering source location ! | |||||
- ResolvedTypeMunger - switch on remembering source location ! |
public final Kind noJoinpointsForBridgeMethods = | public final Kind noJoinpointsForBridgeMethods = | ||||
new Kind("noJoinpointsForBridgeMethods","pointcut did not match on the method call to a bridge method. Bridge methods are generated by the compiler and have no join points"); | new Kind("noJoinpointsForBridgeMethods","pointcut did not match on the method call to a bridge method. Bridge methods are generated by the compiler and have no join points"); | ||||
public final Kind cantMatchArrayTypeOnVarargs = | |||||
new Kind("cantMatchArrayTypeOnVarargs","an array type as the last parameter in a signature does not match on the varargs declared method: {0}"); | |||||
public Lint(World world) { | public Lint(World world) { | ||||
this.world = world; | this.world = world; | ||||
} | } |
noInterfaceCtorJoinpoint = warning | noInterfaceCtorJoinpoint = warning | ||||
noJoinpointsForBridgeMethods = warning | |||||
noJoinpointsForBridgeMethods = warning | |||||
cantMatchArrayTypeOnVarargs = ignore |
import org.aspectj.lang.reflect.ConstructorSignature; | import org.aspectj.lang.reflect.ConstructorSignature; | ||||
import org.aspectj.lang.reflect.FieldSignature; | import org.aspectj.lang.reflect.FieldSignature; | ||||
import org.aspectj.lang.reflect.MethodSignature; | import org.aspectj.lang.reflect.MethodSignature; | ||||
import org.aspectj.weaver.Constants; | |||||
import org.aspectj.weaver.ISourceContext; | import org.aspectj.weaver.ISourceContext; | ||||
import org.aspectj.weaver.Member; | import org.aspectj.weaver.Member; | ||||
import org.aspectj.weaver.NameMangler; | import org.aspectj.weaver.NameMangler; | ||||
return false; | return false; | ||||
} | } | ||||
// If we have matched on parameters, let's just check it isn't because the last parameter in the pattern | |||||
// is an array type and the method is declared with varargs | |||||
if (isNotMatchBecauseOfVarargsIssue(parameterTypes,sig.getModifiers())) { | |||||
world.getLint().cantMatchArrayTypeOnVarargs.signal(sig.toString(),getSourceLocation()); | |||||
return false; | |||||
} | |||||
// Check the throws pattern | // Check the throws pattern | ||||
if (!throwsPattern.matches(sig.getExceptions(), world)) return false; | if (!throwsPattern.matches(sig.getExceptions(), world)) return false; | ||||
if (!parameterTypes.matches(world.resolve(sig.getParameterTypes()), TypePattern.STATIC).alwaysTrue()) { | if (!parameterTypes.matches(world.resolve(sig.getParameterTypes()), TypePattern.STATIC).alwaysTrue()) { | ||||
return false; | return false; | ||||
} | } | ||||
// If we have matched on parameters, let's just check it isn't because the last parameter in the pattern | |||||
// is an array type and the method is declared with varargs | |||||
if (isNotMatchBecauseOfVarargsIssue(parameterTypes,sig.getModifiers())) { | |||||
world.getLint().cantMatchArrayTypeOnVarargs.signal(sig.toString(),getSourceLocation()); | |||||
return false; | |||||
} | |||||
if (!throwsPattern.matches(sig.getExceptions(), world)) return false; | if (!throwsPattern.matches(sig.getExceptions(), world)) return false; | ||||
return declaringType.matchesStatically(member.getDeclaringType().resolve(world)); | return declaringType.matchesStatically(member.getDeclaringType().resolve(world)); | ||||
//return declaringTypeMatch(member.getDeclaringType(), member, world); | //return declaringTypeMatch(member.getDeclaringType(), member, world); | ||||
if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | ||||
return false; | return false; | ||||
} | } | ||||
if (isNotMatchBecauseOfVarargsIssue(parameterTypes,msig.getModifiers())) { return false; } | |||||
if (!throwsPattern.matches(exceptionTypes)) return false; | if (!throwsPattern.matches(exceptionTypes)) return false; | ||||
return declaringTypeMatch(sig); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work | return declaringTypeMatch(sig); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work | ||||
} else if (kind == Member.CONSTRUCTOR) { | } else if (kind == Member.CONSTRUCTOR) { | ||||
if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | ||||
return false; | return false; | ||||
} | } | ||||
if (isNotMatchBecauseOfVarargsIssue(parameterTypes,csig.getModifiers())) { return false; } | |||||
if (!throwsPattern.matches(exceptionTypes)) return false; | if (!throwsPattern.matches(exceptionTypes)) return false; | ||||
return declaringType.matchesStatically(sig.getDeclaringType()); | return declaringType.matchesStatically(sig.getDeclaringType()); | ||||
//return declaringTypeMatch(member.getDeclaringType(), member, world); | //return declaringTypeMatch(member.getDeclaringType(), member, world); | ||||
return false; | return false; | ||||
} | } | ||||
public boolean matches(Class declaringClass, java.lang.reflect.Member member) { | public boolean matches(Class declaringClass, java.lang.reflect.Member member) { | ||||
if (kind == Member.ADVICE) return true; | if (kind == Member.ADVICE) return true; | ||||
if (kind == Member.POINTCUT) return false; | if (kind == Member.POINTCUT) return false; | ||||
if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | ||||
return false; | return false; | ||||
} | } | ||||
if (isNotMatchBecauseOfVarargsIssue(parameterTypes,member.getModifiers())) { return false; } | |||||
if (!throwsPattern.matches(exceptionTypes)) return false; | if (!throwsPattern.matches(exceptionTypes)) return false; | ||||
return declaringTypeMatch(member.getDeclaringClass()); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work | return declaringTypeMatch(member.getDeclaringClass()); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work | ||||
} | } | ||||
if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { | ||||
return false; | return false; | ||||
} | } | ||||
if (isNotMatchBecauseOfVarargsIssue(parameterTypes,member.getModifiers())) { return false; } | |||||
if (!throwsPattern.matches(exceptionTypes)) return false; | if (!throwsPattern.matches(exceptionTypes)) return false; | ||||
return declaringType.matchesStatically(declaringClass); | return declaringType.matchesStatically(declaringClass); | ||||
} | } | ||||
public ThrowsPattern getThrowsPattern() { | public ThrowsPattern getThrowsPattern() { | ||||
return throwsPattern; | return throwsPattern; | ||||
} | } | ||||
/** | |||||
* return true if last argument in params is an Object[] but the modifiers say this method | |||||
* was declared with varargs (Object...). We shouldn't be matching if this is the case. | |||||
*/ | |||||
private boolean isNotMatchBecauseOfVarargsIssue(TypePatternList params,int modifiers) { | |||||
if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0 && // XXX Promote this to an isVarargs() on MethodSignature? | |||||
params.get(params.size()-1).getExactType().isArray()) { | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
} | } |