Use wrapping instead of copying when creating nullable/non-null types
Why wrapping is better: 1. It's requires less memory: a copy has many fields, while a wrapper has only one 2. It preserves laziness of types
This commit is contained in:
@@ -26,6 +26,7 @@ import com.intellij.util.Processor;
|
|||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
@@ -121,7 +122,17 @@ public class TypeUtils {
|
|||||||
if (type.isError()) {
|
if (type.isError()) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), nullable, type.getArguments(), type.getMemberScope());
|
|
||||||
|
// Wrapping serves two purposes here
|
||||||
|
// 1. It's requires less memory than copying with a changed nullability flag: a copy has many fields, while a wrapper has only one
|
||||||
|
// 2. It preserves laziness of types
|
||||||
|
|
||||||
|
// Unwrap to avoid long delegation call chains
|
||||||
|
if (type instanceof AbstractTypeWithKnownNullability) {
|
||||||
|
return makeNullableAsSpecified(((AbstractTypeWithKnownNullability) type).delegate, nullable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullable ? new NullableType(type) : new NotNullType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIntersectionEmpty(@NotNull JetType typeA, @NotNull JetType typeB) {
|
public static boolean isIntersectionEmpty(@NotNull JetType typeA, @NotNull JetType typeB) {
|
||||||
@@ -730,4 +741,85 @@ public class TypeUtils {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static abstract class AbstractTypeWithKnownNullability implements JetType {
|
||||||
|
private final JetType delegate;
|
||||||
|
|
||||||
|
private AbstractTypeWithKnownNullability(@NotNull JetType delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public TypeConstructor getConstructor() {
|
||||||
|
return delegate.getConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
@ReadOnly
|
||||||
|
public List<TypeProjection> getArguments() {
|
||||||
|
return delegate.getArguments();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract boolean isNullable();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JetScope getMemberScope() {
|
||||||
|
return delegate.getMemberScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isError() {
|
||||||
|
return delegate.isError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<AnnotationDescriptor> getAnnotations() {
|
||||||
|
return delegate.getAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
return TypeUtils.equals(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return TypeUtils.hashCode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return TypeUtils.toString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NullableType extends AbstractTypeWithKnownNullability {
|
||||||
|
|
||||||
|
private NullableType(@NotNull JetType delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NotNullType extends AbstractTypeWithKnownNullability {
|
||||||
|
|
||||||
|
private NotNullType(@NotNull JetType delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user