Merge branch 'pr-835'

This commit is contained in:
Andreas Dangel
2018-01-15 20:42:48 +01:00
6 changed files with 80 additions and 4 deletions

View File

@@ -54,6 +54,7 @@ at <https://pmd.github.io/latest/>.
* [#793](https://github.com/pmd/pmd/issues/793): \[java] Parser error with private method in nested classes in interfaces
* [#812](https://github.com/pmd/pmd/issues/812): \[java] Exception applying rule DataClass
* [#814](https://github.com/pmd/pmd/issues/814): \[java] UnsupportedClassVersionError is failure instead of a warning
* [#831](https://github.com/pmd/pmd/issues/831): \[java] StackOverflow in JavaTypeDefinitionSimple.toString
* java-bestpractices
* [#783](https://github.com/pmd/pmd/issues/783): \[java] GuardLogStatement regression
* [#800](https://github.com/pmd/pmd/issues/800): \[java] ForLoopCanBeForeach NPE when looping on `this` object

View File

@@ -158,4 +158,6 @@ public abstract class JavaTypeDefinition implements TypeDefinition {
public abstract JavaTypeDefinition getJavaType(int index);
public abstract int getJavaTypeCount();
protected abstract String shallowString();
}

View File

@@ -241,9 +241,23 @@ import java.util.logging.Logger;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("JavaTypeDefinition [clazz=").append(clazz)
.append(", definitionType=").append(getDefinitionType())
.append(", genericArgs=[");
for (final JavaTypeDefinition jtd : genericArgs) {
sb.append(jtd.shallowString()).append(", ");
}
return sb.replace(sb.length() - 3, sb.length() - 1, "]") // last comma to bracket
.append(", isGeneric=").append(isGeneric)
.append("]\n").toString();
}
@Override
public String shallowString() {
return new StringBuilder("JavaTypeDefinition [clazz=").append(clazz)
.append(", definitionType=").append(getDefinitionType())
.append(", genericArgs=").append(genericArgs)
.append(", isGeneric=").append(isGeneric)
.append("]\n").toString();
}

View File

@@ -111,15 +111,20 @@ import java.util.Set;
public String toString() {
StringBuilder builder = new StringBuilder()
.append("JavaTypeDefinition ")
.append(getDefinitionType().toString())
.append(getDefinitionType())
.append(" [")
.append(typeList[0]);
for (int index = 1; index < typeList.length; ++index) {
builder.append(" && ");
builder.append(typeList[index]);
builder.append(" && ")
.append(typeList[index]);
}
return builder.append("]").toString();
}
@Override
protected String shallowString() {
return toString();
}
@Override
public boolean equals(Object obj) {

View File

@@ -102,6 +102,7 @@ import net.sourceforge.pmd.typeresolution.testdata.MethodThirdPhase;
import net.sourceforge.pmd.typeresolution.testdata.NestedAnonymousClass;
import net.sourceforge.pmd.typeresolution.testdata.Operators;
import net.sourceforge.pmd.typeresolution.testdata.OverloadedMethodsUsage;
import net.sourceforge.pmd.typeresolution.testdata.PmdStackOverflow;
import net.sourceforge.pmd.typeresolution.testdata.Promotion;
import net.sourceforge.pmd.typeresolution.testdata.SubTypeUsage;
import net.sourceforge.pmd.typeresolution.testdata.SuperExpression;
@@ -123,6 +124,12 @@ import net.sourceforge.pmd.typeresolution.testdata.dummytypes.SuperClassB2;
public class ClassTypeResolverTest {
@Test
public void stackOverflowTest() {
// See #831 https://github.com/pmd/pmd/issues/831 - [java] StackOverflow in JavaTypeDefinitionSimple.toString
parseAndTypeResolveForClass15(PmdStackOverflow.class);
}
@Test
public void testClassNameExists() {
ClassTypeResolver classTypeResolver = new ClassTypeResolver();

View File

@@ -0,0 +1,47 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.typeresolution.testdata;
public class PmdStackOverflow {
public void shouldThrowStackOverfloError() {
MessageBuilder messageBuilder = new MessageBuilderA();
// Works
PartBuilder partBuilder = messageBuilder.newComponent();
messageBuilder.addComponent(partBuilder.withSomeValue("ABC"));
// Does not work
messageBuilder.addComponent(messageBuilder.newComponent().withSomeValue("ABC"));
}
}
abstract class MessageBuilder<T extends MessageBuilder, U extends PartBuilder<U>> {
public abstract U newComponent();
public T addComponent(U ignore) {
return (T) this;
}
}
class MessageBuilderA extends MessageBuilder<MessageBuilderA, PartBuilderA> {
@Override
public PartBuilderA newComponent() {
return new PartBuilderA();
}
}
class PartBuilder<T extends PartBuilder> {
public T withSomeValue(String ignore) {
return (T) this;
}
}
class PartBuilderA extends PartBuilder<PartBuilderA> {
}