207 lines
11 KiB
Java
207 lines
11 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2013 IBM Corporation.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial API and implementation
|
|
*******************************************************************************/
|
|
package com.ibm.wala.core.tests.ir;
|
|
|
|
import java.io.IOException;
|
|
import java.util.Collection;
|
|
import java.util.Set;
|
|
|
|
import org.junit.Test;
|
|
|
|
import com.ibm.wala.classLoader.BytecodeClass;
|
|
import com.ibm.wala.classLoader.IBytecodeMethod;
|
|
import com.ibm.wala.classLoader.IClass;
|
|
import com.ibm.wala.classLoader.IField;
|
|
import com.ibm.wala.classLoader.IMethod;
|
|
import com.ibm.wala.core.tests.util.JVMLTestAssertions;
|
|
import com.ibm.wala.core.tests.util.TestAssertions;
|
|
import com.ibm.wala.core.tests.util.WalaTestCase;
|
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
|
import com.ibm.wala.types.ClassLoaderReference;
|
|
import com.ibm.wala.types.FieldReference;
|
|
import com.ibm.wala.types.MethodReference;
|
|
import com.ibm.wala.types.Selector;
|
|
import com.ibm.wala.types.TypeReference;
|
|
import com.ibm.wala.types.annotations.Annotation;
|
|
import com.ibm.wala.util.collections.HashSetFactory;
|
|
import com.ibm.wala.util.collections.Pair;
|
|
import com.ibm.wala.util.strings.Atom;
|
|
|
|
public class AnnotationTest extends WalaTestCase {
|
|
|
|
private final IClassHierarchy cha;
|
|
|
|
private final TestAssertions harness;
|
|
|
|
protected AnnotationTest(TestAssertions harness, IClassHierarchy cha) {
|
|
this.cha = cha;
|
|
this.harness = harness;
|
|
}
|
|
|
|
public AnnotationTest() throws ClassHierarchyException, IOException {
|
|
this(new JVMLTestAssertions(), WalaTestCase.makeCHA());
|
|
}
|
|
|
|
@Test
|
|
public void testClassAnnotations1() throws Exception {
|
|
TypeReference typeUnderTest = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/AnnotatedClass1");
|
|
|
|
Collection<Annotation> expectedRuntimeInvisibleAnnotations = HashSetFactory.make();
|
|
expectedRuntimeInvisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/RuntimeInvisableAnnotation")));
|
|
expectedRuntimeInvisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/DefaultVisableAnnotation")));
|
|
|
|
Collection<Annotation> expectedRuntimeVisibleAnnotations = HashSetFactory.make();
|
|
expectedRuntimeVisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/RuntimeVisableAnnotation")));
|
|
|
|
testClassAnnotations(typeUnderTest, expectedRuntimeInvisibleAnnotations, expectedRuntimeVisibleAnnotations);
|
|
}
|
|
|
|
@Test
|
|
public void testClassAnnotations2() throws Exception {
|
|
TypeReference typeUnderTest = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/AnnotatedClass2");
|
|
|
|
Collection<Annotation> expectedRuntimeInvisibleAnnotations = HashSetFactory.make();
|
|
expectedRuntimeInvisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/RuntimeInvisableAnnotation")));
|
|
expectedRuntimeInvisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/RuntimeInvisableAnnotation2")));
|
|
|
|
Collection<Annotation> expectedRuntimeVisibleAnnotations = HashSetFactory.make();
|
|
expectedRuntimeVisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/RuntimeVisableAnnotation")));
|
|
expectedRuntimeVisibleAnnotations.add(Annotation.make(TypeReference.findOrCreate(ClassLoaderReference.Application,
|
|
"Lannotations/RuntimeVisableAnnotation2")));
|
|
|
|
testClassAnnotations(typeUnderTest, expectedRuntimeInvisibleAnnotations, expectedRuntimeVisibleAnnotations);
|
|
}
|
|
|
|
private void testClassAnnotations(TypeReference typeUnderTest, Collection<Annotation> expectedRuntimeInvisibleAnnotations,
|
|
Collection<Annotation> expectedRuntimeVisibleAnnotations) throws InvalidClassFileException {
|
|
IClass classUnderTest = cha.lookupClass(typeUnderTest);
|
|
harness.assertNotNull(typeUnderTest.toString() + " not found", classUnderTest);
|
|
harness.assertTrue(classUnderTest + " must be BytecodeClass", classUnderTest instanceof BytecodeClass);
|
|
BytecodeClass<?> bcClassUnderTest = (BytecodeClass<?>) classUnderTest;
|
|
|
|
Collection<Annotation> runtimeInvisibleAnnotations = bcClassUnderTest.getAnnotations(true);
|
|
harness.assertEqualCollections(expectedRuntimeInvisibleAnnotations, runtimeInvisibleAnnotations);
|
|
|
|
Collection<Annotation> runtimeVisibleAnnotations = bcClassUnderTest.getAnnotations(false);
|
|
harness.assertEqualCollections(expectedRuntimeVisibleAnnotations, runtimeVisibleAnnotations);
|
|
}
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@Test
|
|
public void testClassAnnotations3() throws Exception {
|
|
|
|
TypeReference typeRef = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/AnnotatedClass3");
|
|
IClass klass = cha.lookupClass(typeRef);
|
|
harness.assertNotNull(typeRef + " must exist", klass);
|
|
BytecodeClass<?> shrikeClass = (BytecodeClass<?>) klass;
|
|
Collection<Annotation> classAnnotations = shrikeClass.getAnnotations(true);
|
|
harness.assertEquals("[Annotation type <Application,Lannotations/AnnotationWithParams> {strParam=classStrParam}]",
|
|
classAnnotations.toString());
|
|
|
|
MethodReference methodRefUnderTest = MethodReference.findOrCreate(typeRef, Selector.make("foo()V"));
|
|
|
|
IMethod methodUnderTest = cha.resolveMethod(methodRefUnderTest);
|
|
harness.assertNotNull(methodRefUnderTest.toString() + " not found", methodUnderTest);
|
|
harness.assertTrue(methodUnderTest + " must be IBytecodeMethod", methodUnderTest instanceof IBytecodeMethod);
|
|
IBytecodeMethod bcMethodUnderTest = (IBytecodeMethod) methodUnderTest;
|
|
|
|
Collection<Annotation> runtimeInvisibleAnnotations = bcMethodUnderTest.getAnnotations(true);
|
|
harness.assertEquals(1, runtimeInvisibleAnnotations.size());
|
|
|
|
Annotation x = runtimeInvisibleAnnotations.iterator().next();
|
|
harness.assertEquals(TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/AnnotationWithParams"), x.getType());
|
|
for(Pair<String,String> n : new Pair[]{Pair.make("enumParam", "EnumElementValue [type=Lannotations/AnnotationEnum;, val=VAL1]"),
|
|
Pair.make("strArrParam", "ArrayElementValue [vals=[biz, boz]]"),
|
|
Pair.make("annotParam", "AnnotationElementValue [type=Lannotations/AnnotationWithSingleParam;, elementValues={value=sdfevs}]"),
|
|
Pair.make("strParam", "sdfsevs"),
|
|
Pair.make("intParam", "25"),
|
|
Pair.make("klassParam", "Ljava/lang/Integer;")}) {
|
|
harness.assertEquals(n.snd, x.getNamedArguments().get(n.fst).toString());
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testClassAnnotations4() throws Exception {
|
|
|
|
TypeReference typeRef = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/AnnotatedClass4");
|
|
FieldReference fieldRefUnderTest = FieldReference.findOrCreate(typeRef, Atom.findOrCreateUnicodeAtom("foo"), TypeReference.Int);
|
|
|
|
IField fieldUnderTest = cha.resolveField(fieldRefUnderTest);
|
|
harness.assertNotNull(fieldRefUnderTest.toString() + " not found", fieldUnderTest);
|
|
|
|
Collection<Annotation> annots = fieldUnderTest.getAnnotations();
|
|
harness.assertEquals(
|
|
"[Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>, Annotation type <Application,Lannotations/RuntimeVisableAnnotation>]",
|
|
annots.toString());
|
|
|
|
}
|
|
|
|
@Test
|
|
public void testParamAnnotations1() throws Exception {
|
|
|
|
TypeReference typeRef = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/ParameterAnnotations1");
|
|
|
|
checkParameterAnnots(typeRef, "foo(Ljava/lang/String;)V",
|
|
new String[]{"Annotation type <Application,Lannotations/RuntimeVisableAnnotation>"});
|
|
checkParameterAnnots(
|
|
typeRef,
|
|
"bar(Ljava/lang/Integer;)V",
|
|
new String[]{"Annotation type <Application,Lannotations/AnnotationWithParams> {annotParam=AnnotationElementValue [type=Lannotations/AnnotationWithSingleParam;, elementValues={value=sdfevs}], enumParam=EnumElementValue [type=Lannotations/AnnotationEnum;, val=VAL1], intParam=25, klassParam=Ljava/lang/Integer;, strArrParam=ArrayElementValue [vals=[biz, boz]], strParam=sdfsevs}"});
|
|
checkParameterAnnots(typeRef, "foo2(Ljava/lang/String;Ljava/lang/Integer;)V",
|
|
new String[]{"Annotation type <Application,Lannotations/RuntimeVisableAnnotation>"},
|
|
new String[]{"Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>"});
|
|
checkParameterAnnots(typeRef, "foo3(Ljava/lang/String;Ljava/lang/Integer;)V",
|
|
new String[]{"Annotation type <Application,Lannotations/RuntimeVisableAnnotation>"},
|
|
new String[]{"Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>"});
|
|
checkParameterAnnots(typeRef, "foo4(Ljava/lang/String;Ljava/lang/Integer;)V",
|
|
new String[]{"Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>", "Annotation type <Application,Lannotations/RuntimeVisableAnnotation>"},
|
|
new String[0]);
|
|
|
|
}
|
|
|
|
protected void checkParameterAnnots(TypeReference typeRef, String selector, String[]... expected) {
|
|
MethodReference methodRefUnderTest = MethodReference.findOrCreate(typeRef, Selector.make(selector));
|
|
|
|
IMethod methodUnderTest = cha.resolveMethod(methodRefUnderTest);
|
|
harness.assertTrue(methodRefUnderTest.toString() + " not found", methodUnderTest != null);
|
|
harness.assertTrue(methodUnderTest + " must be bytecode method", methodUnderTest instanceof IBytecodeMethod);
|
|
IBytecodeMethod IBytecodeMethodUnderTest = (IBytecodeMethod) methodUnderTest;
|
|
|
|
Collection<Annotation>[] parameterAnnotations = IBytecodeMethodUnderTest.getParameterAnnotations();
|
|
harness.assertEquals(expected.length, parameterAnnotations.length);
|
|
for (int i = 0; i < expected.length; i++) {
|
|
Set<String> e = HashSetFactory.make();
|
|
for(String s : expected[i]) {
|
|
e.add(s);
|
|
}
|
|
|
|
Set<String> a = HashSetFactory.make();
|
|
if (parameterAnnotations[i] != null) {
|
|
for(Annotation x : parameterAnnotations[i]) {
|
|
a.add(x.toString());
|
|
}
|
|
}
|
|
|
|
harness.assertTrue(e + " must be " + a, e.equals(a));
|
|
}
|
|
}
|
|
|
|
}
|