Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwharley2012-09-30 14:17:10 +0000
committerJay Arthanareeswaran2015-04-10 07:28:37 +0000
commitfdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4 (patch)
treea3248a8feab560a4a7f906497962e1e6a6fa8275 /org.eclipse.jdt.compiler.apt.tests
parente254cb1235fced696c16505589db91831c0df710 (diff)
downloadeclipse.jdt.core-fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4.tar.gz
eclipse.jdt.core-fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4.tar.xz
eclipse.jdt.core-fdf4380d8dd2e7b1f08462c3e15a52a8d6142eb4.zip
Bug 382590 - Types.asMemberOf() should find members within superclasses.
Also added a bunch of tests of asMemberOf() both for the regular and superclass cases. Change-Id: If316ace90470cd0041542b9562abf3575d377254
Diffstat (limited to 'org.eclipse.jdt.compiler.apt.tests')
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jarbin189469 -> 193057 bytes
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java190
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java55
3 files changed, 218 insertions, 27 deletions
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
index 1b5f5ed691..f084ec1f37 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java
index e869708c6b..73130a8d99 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/typeutils/TypeUtilsProc.java
@@ -1,16 +1,19 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 BEA Systems, Inc. and others
+ * Copyright (c) 2007 - 2012 BEA Systems, Inc. and others
* 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:
- * wharley@bea.com - initial API and implementation
+ * Walter Harley - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.compiler.apt.tests.processors.typeutils;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -19,15 +22,19 @@ import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
+import org.eclipse.jdt.internal.compiler.apt.model.DeclaredTypeImpl;
/**
* A processor that exercises the methods on the Elements utility. To enable this processor, add
@@ -38,7 +45,6 @@ import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class TypeUtilsProc extends BaseProcessor
{
-
// Always return false from this processor, because it supports "*".
// The return value does not signify success or failure!
@Override
@@ -54,28 +60,44 @@ public class TypeUtilsProc extends BaseProcessor
return false;
}
- if (!examinePrimitives()) {
- return false;
- }
-
- if (!examineNoType()) {
- return false;
- }
-
- if (!examineGetDeclaredType()) {
- return false;
- }
-
- if (!examineGetDeclaredTypeParameterized()) {
- return false;
- }
-
- if (!examineGetDeclaredTypeNested()) {
- return false;
- }
-
- if (!examineGetArrayTypeParameterized()) {
- return false;
+ try {
+ if (!examinePrimitives()) {
+ return false;
+ }
+
+ if (!examineNoType()) {
+ return false;
+ }
+
+ if (!examineGetDeclaredType()) {
+ return false;
+ }
+
+ if (!examineGetDeclaredTypeParameterized()) {
+ return false;
+ }
+
+ if (!examineGetDeclaredTypeNested()) {
+ return false;
+ }
+
+ if (!examineGetArrayTypeParameterized()) {
+ return false;
+ }
+
+ if (!examineTypesAsMemberOf()) {
+ return false;
+ }
+
+ if (!examineTypesAsMemberOfSubclass()) {
+ return false;
+ }
+ } catch (RuntimeException e) {
+ StringWriter sw = new StringWriter();
+ PrintWriter w = new PrintWriter(sw);
+ e.printStackTrace(w);
+ reportError(sw.toString());
+ return false;
}
reportSuccess();
@@ -246,7 +268,7 @@ public class TypeUtilsProc extends BaseProcessor
*/
private boolean examineGetDeclaredTypeParameterized() {
TypeElement stringDecl = _elementUtils.getTypeElement(String.class.getName());
- TypeElement mapDecl = _elementUtils.getTypeElement("java.util.Map");
+ TypeElement mapDecl = _elementUtils.getTypeElement(Map.class.getName());
DeclaredType stringType = _typeUtils.getDeclaredType(stringDecl);
ArrayType stringArrayType = _typeUtils.getArrayType(stringType);
@@ -297,7 +319,7 @@ public class TypeUtilsProc extends BaseProcessor
}
return true;
}
-
+
/**
* Test getArrayType() for a parameterized type
* @return true if tests passed
@@ -322,4 +344,118 @@ public class TypeUtilsProc extends BaseProcessor
return true;
}
+ /**
+ * Test {@link Types#asMemberOf()}.
+ * @return true if tests passed
+ */
+ private boolean examineTypesAsMemberOf() {
+ TypeElement containerElement = _elementUtils.getTypeElement("targets.model.pc.AsMemberOf");
+ DeclaredType longType = (DeclaredType)_elementUtils.getTypeElement("java.lang.Long").asType();
+ DeclaredType container = _typeUtils.getDeclaredType(containerElement, longType);
+ return innerTestAsMemberOf("examineTypesAsMemberOf", container, containerElement);
+ }
+ /**
+ * Test {@link Types#asMemberOf()} where the elements are members of a superclass of the
+ * declared container. See <a href="http://bugs.eclipse.org/382590">Bug 382590</a>. Note that
+ * the asMemberOf() javadoc says the element is viewed "as a member of, or otherwise directly
+ * contained by, a given type." It is not clear what "directly" means here, but javac 1.6
+ * supports this case, so we will too.
+ * @return true if tests passed
+ */
+ private boolean examineTypesAsMemberOfSubclass() {
+ DeclaredType declaredContainer = (DeclaredType) _elementUtils.getTypeElement("targets.model.pc.AsMemberOfSub").asType();
+ TypeElement containerElement = _elementUtils.getTypeElement("targets.model.pc.AsMemberOf");
+ return innerTestAsMemberOf("examineTypesAsMemberOfSubclass", declaredContainer, containerElement);
+ }
+
+ /**
+ * @return true if tests passed
+ */
+ private boolean innerTestAsMemberOf(String method, DeclaredType declaredContainer,
+ TypeElement containerElement) {
+ DeclaredType longType = (DeclaredType)_elementUtils.getTypeElement("java.lang.Long").asType();
+ Map<String, Element> members = new HashMap<String, Element>();
+ for (Element element : containerElement.getEnclosedElements()) {
+ members.put(element.getSimpleName().toString(), element);
+ }
+ for (String m : new String[] {"f2", "m2"}) {
+ if (members.get(m) != null) {
+ reportError(method + ": Should not have found member named '" + m + "' in container " + declaredContainer);
+ return false;
+ }
+ }
+ for (String m : new String[] {"f", "m", "C", "D", "e"}) {
+ Element memberElement = members.get(m);
+ if (memberElement == null) {
+ reportError(method + ": Couldn't find member named '" + m + "' in container " + declaredContainer);
+ return false;
+ }
+ TypeMirror tm = _typeUtils.asMemberOf(declaredContainer, memberElement);
+
+ if ("f".equals(m)) {
+ // Long field
+ if (!_typeUtils.isSameType(tm, longType)) {
+ reportError(method + ": member f should be of type Long, but was " + tm);
+ return false;
+ }
+ } else if ("m".equals(m)) {
+ // void method returning Long
+ if (tm.getKind() != TypeKind.EXECUTABLE) {
+ reportError(method + ": member m() should be executable but was " + tm.getKind());
+ return false;
+ }
+ ExecutableType etm = (ExecutableType)tm;
+ if (!etm.getParameterTypes().isEmpty()) {
+ reportError(method + ": member m() should be void, but it had parameters");
+ return false;
+ }
+ if (!_typeUtils.isSameType(etm.getReturnType(), longType)) {
+ reportError(method + ": member m() should have Long return type, but found " + etm.getReturnType());
+ return false;
+ }
+ } else if ("C".equals(m)) {
+ // Not clear what to expect in the case of a static nested class. Outer parameterization doesn't
+ // apply to the nested class; and the method spec doesn't say what to do when the contained
+ // member is incompletely parameterized.
+ TypeElement c = _elementUtils.getTypeElement("targets.model.pc.AsMemberOf.C");
+ TypeMirror tmExpected = c.asType();
+
+ // In javac, we get A.C<T> whether C is directly contained or accessed via a subclass.
+ // In Eclipse, when accessing through a subclass, the binding to C is lazily created
+ // within ParameterizedTypeBinding.memberTypes(), so it gets created as a PTB itself,
+ // with no type arguments. Thus it is A<Long>.C instead of A.C<T>. This is probably a
+ // compiler bug, but given that asMemberOf() is documented to apply only to "directly
+ // contained" members it's probably not worth worrying about. So, we accept that case.
+ if (!_typeUtils.isSameType(tm, tmExpected) &&
+ !(tm instanceof DeclaredTypeImpl &&
+ "targets.model.pc.AsMemberOf<java.lang.Long>.C".equals(tm.toString()))) {
+ reportError(method + ": member C: Expected type " + tmExpected + " but found " + tm);
+ return false;
+ }
+ } else if ("D".equals(m)) {
+ // Expected type of D is AsMemberOf2<Long>.D
+ DeclaredType tmContainer = _typeUtils.getDeclaredType(containerElement, longType);
+ TypeElement d = _elementUtils.getTypeElement("targets.model.pc.AsMemberOf.D");
+ TypeMirror tmExpected = _typeUtils.getDeclaredType(tmContainer, d);
+ if (!_typeUtils.isSameType(tm, tmExpected)) {
+ reportError(method + ": member D: Expected type " + tmExpected +
+ " but found " + tm);
+ return false;
+ }
+ } else if ("e".equals(m)) {
+ // Expected type of e is A<Long>.E<Integer>
+ DeclaredType tmContainer = _typeUtils.getDeclaredType(containerElement, longType);
+ TypeElement eTypeElem = _elementUtils.getTypeElement("targets.model.pc.AsMemberOf.E");
+ DeclaredType tmInt = (DeclaredType) _elementUtils.getTypeElement("java.lang.Integer").asType();
+ TypeMirror tmExpected = _typeUtils.getDeclaredType(tmContainer, eTypeElem, tmInt);
+ if (!_typeUtils.isSameType(tm, tmExpected)) {
+ reportError(method + ": member e: Expected type " + tmExpected +
+ " but found " + tm);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java
new file mode 100644
index 0000000000..5df21e72fa
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/targets/model/pc/AsMemberOf.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Walter Harley and others
+ * 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
+ *******************************************************************************/
+package targets.model.pc;
+
+/**
+ * Bug 382590 says that Types.asMemberOf(x, y) should work when x is a subclass
+ * of the class containing y.
+ *
+ * See TypeUtilsProc.java, which gets exercised by ModelUtilTests.testTypes*().
+ */
+public class AsMemberOf<T> {
+ private T f;
+ private T m() { return f; }
+ E<Integer> e = new E<Integer>();
+
+ // Type parameter 'T' of static class is unrelated to 'T' of containing class
+ private static class C<T> {
+ T x() { return null; }
+ }
+
+ // Type parameter 'T' of inner class is inherited from the containing class
+ private class D {
+ T x() { return null; }
+ }
+
+ // Both container and contained are parameterized
+ class E<T2> {
+ T x() { return null; }
+ T2 y() { return null; }
+ }
+
+ // Need this so that compiler doesn't complain about unused private members.
+ // Members are private to verify that asMemberOf() does not consider visibility,
+ // even when accesed through a subclass; this is not explicitly specified, but
+ // is true for javac 1.6.
+ T publicize() {
+ return (m() == null) ? new C<T>().x() : new D().x();
+ }
+}
+
+interface IAsMemberOf<T> {
+ // Types.asMemberOf() should not find members in superinterfaces
+ void m2();
+}
+
+abstract class AsMemberOfSub extends AsMemberOf<Long> implements IAsMemberOf<Long> {
+ // m2 not implemented; thus class must be abstract
+ // f2() intentionally not defined; negative test
+}
+

Back to the top