From 50a2e9fdcfc64160a3dadb2cd3bdf3336e99cb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 6 Jul 2017 17:48:41 -0300 Subject: [PATCH 1/3] Fix typeresolution for anonymous extending object - This is really an edge case, with little or no real-world scenarios, just fix it for completeness --- .../typedefinition/JavaTypeDefinition.java | 8 +++++++- .../typeresolution/ClassTypeResolverTest.java | 9 +++++++++ .../testdata/AnoymousExtendingObject.java | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/AnoymousExtendingObject.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java index e57306bcb9..cd8a2a15bc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java @@ -30,7 +30,13 @@ public class JavaTypeDefinition implements TypeDefinition { if (clazz.isAnonymousClass()) { // is this an anonymous class based on an interface or a class? if (clazz.getSuperclass() == Object.class) { - typeParameters = clazz.getInterfaces()[0].getTypeParameters(); + // is this based off an interface? + if (clazz.getInterfaces().length != 0) { + typeParameters = clazz.getInterfaces()[0].getTypeParameters(); + } else { + // This guy is just doing new Object() { ... } + typeParameters = clazz.getTypeParameters(); + } } else { typeParameters = clazz.getSuperclass().getTypeParameters(); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java index 4cb43afaa5..5a37f2b821 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java @@ -52,6 +52,7 @@ import net.sourceforge.pmd.lang.java.typeresolution.ClassTypeResolver; import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition; import net.sourceforge.pmd.typeresolution.testdata.AnonymousClassFromInterface; import net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass; +import net.sourceforge.pmd.typeresolution.testdata.AnoymousExtendingObject; import net.sourceforge.pmd.typeresolution.testdata.ArrayListFound; import net.sourceforge.pmd.typeresolution.testdata.DefaultJavaLangImport; import net.sourceforge.pmd.typeresolution.testdata.EnumWithAnonymousInnerClass; @@ -192,6 +193,14 @@ public class ClassTypeResolverTest { Assert.assertTrue(Converter.class.isAssignableFrom(child.getType())); Assert.assertSame(String.class, child.getTypeDefinition().getGenericType(0).getType()); } + + @Test + public void testAnoymousExtendingObject() throws Exception { + Node acu = parseAndTypeResolveForClass(AnoymousExtendingObject.class, "1.8"); + ASTAllocationExpression allocationExpression = acu.getFirstDescendantOfType(ASTAllocationExpression.class); + TypeNode child = (TypeNode) allocationExpression.jjtGetChild(0); + Assert.assertTrue(Object.class.isAssignableFrom(child.getType())); + } @Test public void testAnonymousInnerClass() throws ClassNotFoundException { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/AnoymousExtendingObject.java b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/AnoymousExtendingObject.java new file mode 100644 index 0000000000..8138551400 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/AnoymousExtendingObject.java @@ -0,0 +1,17 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.typeresolution.testdata; + +public class AnoymousExtendingObject { + + public void foo() { + System.out.println(new Object() { + @Override + public String toString() { + return "Suprise!"; + } + }); + } +} From e56bf2a407b4358f735e85a345c58f40607ea51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sat, 8 Jul 2017 17:10:56 -0300 Subject: [PATCH 2/3] Simplify solution --- .../typedefinition/JavaTypeDefinition.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java index cd8a2a15bc..86e8ea1689 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/typedefinition/JavaTypeDefinition.java @@ -29,14 +29,8 @@ public class JavaTypeDefinition implements TypeDefinition { // the anonymous class can't have generics, but we may be binding generics from super classes if (clazz.isAnonymousClass()) { // is this an anonymous class based on an interface or a class? - if (clazz.getSuperclass() == Object.class) { - // is this based off an interface? - if (clazz.getInterfaces().length != 0) { - typeParameters = clazz.getInterfaces()[0].getTypeParameters(); - } else { - // This guy is just doing new Object() { ... } - typeParameters = clazz.getTypeParameters(); - } + if (clazz.getInterfaces().length != 0) { + typeParameters = clazz.getInterfaces()[0].getTypeParameters(); } else { typeParameters = clazz.getSuperclass().getTypeParameters(); } From 230994848a74a13c506496562623daeb091aac81 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 17 Jul 2017 20:50:50 +0200 Subject: [PATCH 3/3] Update changelog, refs #487 --- src/site/markdown/overview/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md index 1b4e6228ba..cc8e601220 100644 --- a/src/site/markdown/overview/changelog.md +++ b/src/site/markdown/overview/changelog.md @@ -66,6 +66,7 @@ Based on those metrics, rules like "GodClass" detection can be implemented more * [#448](https://github.com/pmd/pmd/issues/448): \[cpp] Write custom CharStream to handle continuation characters * java * [#1513](https://sourceforge.net/p/pmd/bugs/1513/): \[java] Remove deprecated rule UseSingleton + * [#487](https://github.com/pmd/pmd/pull/487): \[java] Fix typeresolution for anonymous extending object * java-controversial * [#408](https://github.com/pmd/pmd/issues/408): \[java] DFA not analyzing asserts * java-unnecessarycode