[java] Resolve StackOverflow in JavaTypeDefinitionSimple.toString()
- Resolves #831
This commit is contained in:
@ -158,4 +158,6 @@ public abstract class JavaTypeDefinition implements TypeDefinition {
|
||||
public abstract JavaTypeDefinition getJavaType(int index);
|
||||
|
||||
public abstract int getJavaTypeCount();
|
||||
|
||||
protected abstract String shallowString();
|
||||
}
|
||||
|
@ -21,8 +21,10 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/* default */ class JavaTypeDefinitionSimple extends JavaTypeDefinition {
|
||||
@ -243,7 +245,21 @@ import java.util.logging.Logger;
|
||||
public String toString() {
|
||||
return new StringBuilder("JavaTypeDefinition [clazz=").append(clazz)
|
||||
.append(", definitionType=").append(getDefinitionType())
|
||||
.append(", genericArgs=").append(genericArgs)
|
||||
.append(", genericArgs=").append(genericArgs.stream().map(new Function<JavaTypeDefinition, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(final JavaTypeDefinition jtd) {
|
||||
return jtd.shallowString();
|
||||
}
|
||||
}).collect(Collectors.toList()))
|
||||
.append(", isGeneric=").append(isGeneric)
|
||||
.append("]\n").toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shallowString() {
|
||||
return new StringBuilder("JavaTypeDefinition [clazz=").append(clazz)
|
||||
.append(", definitionType=").append(getDefinitionType())
|
||||
.append(", isGeneric=").append(isGeneric)
|
||||
.append("]\n").toString();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
47
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/PmdStackOverflow.java
vendored
Normal file
47
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/PmdStackOverflow.java
vendored
Normal 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> {
|
||||
}
|
Reference in New Issue
Block a user