Add extra diagnostic information when no common supertypes are found

We're suspecting that the culprit of such errors is race condition on
'supertypes' in AbstractTypeConstructor, when it is created using
'LockBasedStorageManager.NO_LOCKS'
This commit is contained in:
Dmitry Savvinov
2018-04-09 13:13:27 +03:00
parent 9455f50e58
commit d8b7de4f0e
4 changed files with 51 additions and 6 deletions
@@ -142,15 +142,15 @@ public class CommonSupertypes {
if (commonSupertypes.isEmpty()) {
StringBuilder info = new StringBuilder();
for (SimpleType type : types) {
String superTypes = type.getConstructor().getSupertypes().stream()
.map(CommonSupertypes::renderTypeFully)
.collect(Collectors.joining(", "));
String superTypes = TypeUtils.getAllSupertypes(type).stream()
.map(t -> "-- " + renderTypeFully(t))
.collect(Collectors.joining("\n"));
info
.append("Info about ").append(renderTypeFully(type)).append(": ").append('\n')
.append("- Supertypes: ").append(superTypes).append('\n')
.append("- Supertypes: ").append('\n')
.append(superTypes).append('\n')
.append("- DeclarationDescriptor class: ").append(classOfDeclarationDescriptor(type)).append('\n')
.append("- TypeConstructor class: ").append(type.getConstructor().getClass()).append('\n')
.append('\n');
}
throw new IllegalStateException("There is no common supertype for: " + types + " \n" + info.toString());
@@ -166,7 +166,18 @@ public class CommonSupertypes {
@NotNull
private static String renderTypeFully(@NotNull KotlinType type) {
return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type);
return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type) + ", typeConstructor debug: " +
renderTypeConstructorVerboseDebugInformation(type.getConstructor());
}
@SuppressWarnings("deprecation")
private static String renderTypeConstructorVerboseDebugInformation(TypeConstructor typeConstructor) {
if (!(typeConstructor instanceof AbstractTypeConstructor)) {
return typeConstructor.toString() + "[" + typeConstructor.getClass().getName() + "]";
}
AbstractTypeConstructor abstractTypeConstructor = (AbstractTypeConstructor) typeConstructor;
return abstractTypeConstructor.renderAdditionalDebugInformation();
}
@Nullable
@@ -76,4 +76,6 @@ abstract class AbstractTypeConstructor(storageManager: StorageManager) : TypeCon
protected open fun getAdditionalNeighboursInSupertypeGraph(useCompanions: Boolean): Collection<KotlinType> = emptyList()
protected open fun defaultSupertypeIfEmpty(): KotlinType? = null
// Only for debugging
fun renderAdditionalDebugInformation(): String = "supertypes=${supertypes.renderDebugInformation()}"
}
@@ -146,6 +146,11 @@ public class LockBasedStorageManager implements StorageManager {
protected RecursionDetectedResult<T> recursionDetected(boolean firstTime) {
return RecursionDetectedResult.value(onRecursiveCall);
}
@Override
protected String presentableName() {
return "RecursionTolerantLazyValue";
}
};
}
@@ -170,6 +175,11 @@ public class LockBasedStorageManager implements StorageManager {
protected void postCompute(@NotNull T value) {
postCompute.invoke(value);
}
@Override
protected String presentableName() {
return "LazyValueWithPostCompute";
}
};
}
@@ -188,6 +198,11 @@ public class LockBasedStorageManager implements StorageManager {
protected RecursionDetectedResult<T> recursionDetected(boolean firstTime) {
return RecursionDetectedResult.value(onRecursiveCall);
}
@Override
protected String presentableName() {
return "RecursionTolerantNullableLazyValue";
}
};
}
@@ -201,6 +216,11 @@ public class LockBasedStorageManager implements StorageManager {
protected void postCompute(@Nullable T value) {
postCompute.invoke(value);
}
@Override
protected String presentableName() {
return "NullableLazyValueWithPostCompute";
}
};
}
@@ -356,6 +376,15 @@ public class LockBasedStorageManager implements StorageManager {
protected void postCompute(T value) {
// Doing something in post-compute helps prevent infinite recursion
}
@NotNull
public String renderDebugInformation() {
return presentableName() + ", storageManager=" + storageManager;
}
protected String presentableName() {
return this.getClass().getName();
}
}
private static class LockBasedNotNullLazyValue<T> extends LockBasedLazyValue<T> implements NotNullLazyValue<T> {
@@ -29,6 +29,9 @@ interface MemoizedFunctionToNullable<in P, out R : Any> : Function1<P, R?> {
interface NotNullLazyValue<out T : Any> : Function0<T> {
fun isComputed(): Boolean
fun isComputing(): Boolean
// Only for debugging
fun renderDebugInformation(): String = ""
}
interface NullableLazyValue<out T : Any> : Function0<T?> {