Introduce AbstractTypeParameterDescriptor

- pull the logic up from TypeParameterDescriptorImpl and
  AbstractLazyTypeParameterDescriptor (it was mostly duplicated)
- delete some unused methods
This commit is contained in:
Alexander Udalov
2014-05-16 19:04:22 +04:00
parent 31e8622471
commit 54a44b1533
5 changed files with 210 additions and 353 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.lazy.descriptors;
import com.google.common.collect.Sets;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AbstractLazyTypeParameterDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -34,7 +33,7 @@ import org.jetbrains.jet.lexer.JetTokens;
import java.util.Set;
public class LazyTypeParameterDescriptor extends AbstractLazyTypeParameterDescriptor implements TypeParameterDescriptor, LazyEntity {
public class LazyTypeParameterDescriptor extends AbstractLazyTypeParameterDescriptor implements LazyEntity {
private final ResolveSession resolveSession;
private final JetTypeParameter jetTypeParameter;
@@ -125,7 +124,6 @@ public class LazyTypeParameterDescriptor extends AbstractLazyTypeParameterDescri
getDefaultType();
getIndex();
ForceResolveUtil.forceResolveAllContents(getLowerBounds());
getLowerBoundsAsType();
getOriginal();
ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
ForceResolveUtil.forceResolveAllContents(getUpperBounds());
@@ -39,9 +39,6 @@ public interface TypeParameterDescriptor extends ClassifierDescriptor {
@NotNull
Set<JetType> getLowerBounds();
@NotNull
JetType getLowerBoundsAsType();
@NotNull
@Override
TypeConstructor getTypeConstructor();
@@ -16,141 +16,36 @@
package org.jetbrains.jet.lang.descriptors.impl;
import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.storage.StorageManager;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public abstract class AbstractLazyTypeParameterDescriptor implements TypeParameterDescriptor {
private final Variance variance;
private final boolean reified;
private final int index;
private final DeclarationDescriptor containingDeclaration;
private final Name name;
private final NotNullLazyValue<TypeConstructor> typeConstructor;
private final NotNullLazyValue<JetType> defaultType;
private final NotNullLazyValue<Set<JetType>> upperBounds;
private final NotNullLazyValue<JetType> upperBoundsAsType;
public abstract class AbstractLazyTypeParameterDescriptor extends AbstractTypeParameterDescriptor {
public AbstractLazyTypeParameterDescriptor(
@NotNull final StorageManager storageManager,
@NotNull StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull Variance variance,
boolean isReified,
int index
) {
this.variance = variance;
this.containingDeclaration = containingDeclaration;
this.index = index;
this.name = name;
this.reified = isReified;
this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
@Override
public TypeConstructor invoke() {
return createTypeConstructor();
}
});
this.defaultType = storageManager.createLazyValue(new Function0<JetType>() {
@Override
public JetType invoke() {
return createDefaultType(storageManager);
}
});
this.upperBounds = storageManager.createLazyValue(new Function0<Set<JetType>>() {
@Override
public Set<JetType> invoke() {
return resolveUpperBounds();
}
});
this.upperBoundsAsType = storageManager.createLazyValue(new Function0<JetType>() {
@Override
public JetType invoke() {
return computeUpperBoundsAsType();
}
});
}
@Override
public boolean isReified() {
return reified;
super(storageManager, containingDeclaration, Annotations.EMPTY /* TODO */, name, variance, isReified, index);
}
@NotNull
@Override
public Variance getVariance() {
return variance;
}
@NotNull
@Override
public Set<JetType> getUpperBounds() {
return upperBounds.invoke();
}
@NotNull
@ReadOnly
protected abstract Set<JetType> resolveUpperBounds();
@NotNull
@Override
public JetType getUpperBoundsAsType() {
return upperBoundsAsType.invoke();
}
@NotNull
private JetType computeUpperBoundsAsType() {
Set<JetType> upperBounds = getUpperBounds();
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
if (upperBoundsAsType == null) {
upperBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
}
return upperBoundsAsType;
}
@NotNull
@Override
public Set<JetType> getLowerBounds() {
return Collections.singleton(getLowerBoundsAsType());
}
@NotNull
@Override
public JetType getLowerBoundsAsType() {
return KotlinBuiltIns.getInstance().getNothingType();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return typeConstructor.invoke();
}
@NotNull
private TypeConstructor createTypeConstructor() {
protected TypeConstructor createTypeConstructor() {
return new TypeConstructor() {
@NotNull
@Override
@@ -191,85 +86,4 @@ public abstract class AbstractLazyTypeParameterDescriptor implements TypeParamet
}
};
}
@NotNull
@Override
public JetType getDefaultType() {
return defaultType.invoke();
}
@NotNull
private JetType createDefaultType(@NotNull StorageManager storageManager) {
return new JetTypeImpl(Annotations.EMPTY, getTypeConstructor(), false, Collections.<TypeProjection>emptyList(),
new LazyScopeAdapter(storageManager.createLazyValue(
new Function0<JetScope>() {
@Override
public JetScope invoke() {
return getUpperBoundsAsType().getMemberScope();
}
}
))
);
}
@Override
public JetType getClassObjectType() {
return null;
}
@NotNull
@Override
public DeclarationDescriptor getOriginal() {
return this;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration;
}
@NotNull
@Override
@Deprecated
public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
throw new UnsupportedOperationException("Don't call substitute() on type parameters");
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitTypeParameterDescriptor(this, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
visitor.visitTypeParameterDescriptor(this, null);
}
@Override
public int getIndex() {
return index;
}
@NotNull
@Override
public Annotations getAnnotations() {
return Annotations.EMPTY; // TODO
}
@NotNull
@Override
public Name getName() {
return name;
}
@Override
public String toString() {
try {
return DescriptorRenderer.DEBUG_TEXT.render(this);
}
catch (Exception e) {
return this.getClass().getName() + "@" + System.identityHashCode(this);
}
}
}
}
@@ -0,0 +1,174 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors.impl;
import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.storage.StorageManager;
import java.util.Collections;
import java.util.Set;
public abstract class AbstractTypeParameterDescriptor extends DeclarationDescriptorNonRootImpl implements TypeParameterDescriptor {
private final Variance variance;
private final boolean reified;
private final int index;
private final NotNullLazyValue<TypeConstructor> typeConstructor;
private final NotNullLazyValue<JetType> defaultType;
private final NotNullLazyValue<Set<JetType>> upperBounds;
private final NotNullLazyValue<JetType> upperBoundsAsType;
protected AbstractTypeParameterDescriptor(
@NotNull final StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Annotations annotations,
@NotNull Name name,
@NotNull Variance variance,
boolean isReified,
int index
) {
super(containingDeclaration, annotations, name);
this.variance = variance;
this.reified = isReified;
this.index = index;
this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
@Override
public TypeConstructor invoke() {
return createTypeConstructor();
}
});
this.defaultType = storageManager.createLazyValue(new Function0<JetType>() {
@Override
public JetType invoke() {
return new JetTypeImpl(Annotations.EMPTY, getTypeConstructor(), false, Collections.<TypeProjection>emptyList(),
new LazyScopeAdapter(storageManager.createLazyValue(
new Function0<JetScope>() {
@Override
public JetScope invoke() {
return getUpperBoundsAsType().getMemberScope();
}
}
)));
}
});
this.upperBounds = storageManager.createLazyValue(new Function0<Set<JetType>>() {
@Override
public Set<JetType> invoke() {
return resolveUpperBounds();
}
});
this.upperBoundsAsType = storageManager.createLazyValue(new Function0<JetType>() {
@Override
public JetType invoke() {
return computeUpperBoundsAsType();
}
});
}
@NotNull
@ReadOnly
protected abstract Set<JetType> resolveUpperBounds();
@NotNull
protected abstract TypeConstructor createTypeConstructor();
@NotNull
@Override
public Variance getVariance() {
return variance;
}
@Override
public boolean isReified() {
return reified;
}
@Override
public int getIndex() {
return index;
}
@NotNull
@Override
public Set<JetType> getUpperBounds() {
return upperBounds.invoke();
}
@NotNull
@Override
public JetType getUpperBoundsAsType() {
return upperBoundsAsType.invoke();
}
@NotNull
private JetType computeUpperBoundsAsType() {
Set<JetType> upperBounds = getUpperBounds();
assert !upperBounds.isEmpty() : "Upper bound list is empty in " + getName();
JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
return upperBoundsAsType != null ? upperBoundsAsType : KotlinBuiltIns.getInstance().getNothingType();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return typeConstructor.invoke();
}
@NotNull
@Override
public JetType getDefaultType() {
return defaultType.invoke();
}
@Override
public JetType getClassObjectType() {
// TODO: class object bounds
return null;
}
@NotNull
@Override
public Set<JetType> getLowerBounds() {
return Collections.singleton(KotlinBuiltIns.getInstance().getNothingType());
}
@NotNull
@Override
@Deprecated
public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
throw new UnsupportedOperationException("Don't call substitute() on type parameters");
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitTypeParameterDescriptor(this, data);
}
}
@@ -17,34 +17,31 @@
package org.jetbrains.jet.lang.descriptors.impl;
import com.google.common.collect.Sets;
import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeConstructorImpl;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.storage.LockBasedStorageManager;
import java.util.Collections;
import java.util.Set;
import static org.jetbrains.jet.storage.LockBasedStorageManager.NO_LOCKS;
public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImpl implements TypeParameterDescriptor {
public class TypeParameterDescriptorImpl extends AbstractTypeParameterDescriptor {
public static TypeParameterDescriptor createWithDefaultBound(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Annotations annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
int index
) {
TypeParameterDescriptorImpl typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index);
typeParameterDescriptor.addUpperBound(KotlinBuiltIns.getInstance().getDefaultBound());
typeParameterDescriptor.setInitialized();
@@ -57,22 +54,12 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
int index
) {
return new TypeParameterDescriptorImpl(containingDeclaration, annotations, reified, variance, name, index);
}
// 0-based
private final int index;
private final Variance variance;
private final Set<JetType> upperBounds;
private JetType upperBoundsAsType;
private final TypeConstructor typeConstructor;
private JetType defaultType;
private final Set<JetType> classObjectUpperBounds = Sets.newLinkedHashSet();
private JetType classObjectBoundsAsType;
private final boolean reified;
private final Set<JetType> upperBounds = Sets.newLinkedHashSet();
private boolean initialized = false;
private TypeParameterDescriptorImpl(
@@ -81,20 +68,23 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
super(containingDeclaration, annotations, name);
this.index = index;
this.variance = variance;
this.upperBounds = Sets.newLinkedHashSet();
this.reified = reified;
int index
) {
super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, annotations, name, variance, reified, index);
}
@NotNull
@Override
protected TypeConstructor createTypeConstructor() {
// TODO: Should we actually pass the annotations on to the type constructor?
this.typeConstructor = new TypeConstructorImpl(
return new TypeConstructorImpl(
this,
annotations,
getAnnotations(),
false,
name.asString(),
getName().asString(),
Collections.<TypeParameterDescriptor>emptyList(),
upperBounds);
upperBounds
);
}
private void checkInitialized() {
@@ -118,18 +108,6 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp
initialized = true;
}
@Override
public boolean isReified() {
checkInitialized();
return reified;
}
@Override
@NotNull
public Variance getVariance() {
return variance;
}
public void addUpperBound(@NotNull JetType bound) {
checkUninitialized();
doAddUpperBound(bound);
@@ -147,114 +125,10 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp
}
}
@Override
@NotNull
public Set<JetType> getUpperBounds() {
@Override
protected Set<JetType> resolveUpperBounds() {
checkInitialized();
return upperBounds;
}
@Override
@NotNull
public JetType getUpperBoundsAsType() {
checkInitialized();
if (upperBoundsAsType == null) {
assert upperBounds != null : "Upper bound list is null in " + getName();
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
if (upperBoundsAsType == null) {
upperBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
}
}
return upperBoundsAsType;
}
@Override
@NotNull
public Set<JetType> getLowerBounds() {
//checkInitialized();
return Collections.singleton(KotlinBuiltIns.getInstance().getNothingType());
}
@Override
@NotNull
public JetType getLowerBoundsAsType() {
checkInitialized();
return KotlinBuiltIns.getInstance().getNothingType();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
//checkInitialized();
return typeConstructor;
}
@Override
public String toString() {
try {
return DescriptorRenderer.FQ_NAMES_IN_TYPES.render(this);
} catch (Exception e) {
return this.getClass().getName() + "@" + System.identityHashCode(this);
}
}
@NotNull
@Override
@Deprecated
public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
throw new UnsupportedOperationException();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
checkInitialized();
return visitor.visitTypeParameterDescriptor(this, data);
}
@NotNull
@Override
public JetType getDefaultType() {
//checkInitialized();
if (defaultType == null) {
defaultType = new JetTypeImpl(
Annotations.EMPTY,
getTypeConstructor(),
TypeUtils.hasNullableLowerBound(this),
Collections.<TypeProjection>emptyList(),
new LazyScopeAdapter(NO_LOCKS.createLazyValue(new Function0<JetScope>() {
@Override
public JetScope invoke() {
return getUpperBoundsAsType().getMemberScope();
}
})));
}
return defaultType;
}
@Override
public JetType getClassObjectType() {
checkInitialized();
if (classObjectUpperBounds.isEmpty()) return null;
if (classObjectBoundsAsType == null) {
classObjectBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, classObjectUpperBounds);
if (classObjectBoundsAsType == null) {
classObjectBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
}
}
return classObjectBoundsAsType;
}
public void addClassObjectBound(@NotNull JetType bound) {
checkUninitialized();
classObjectUpperBounds.add(bound); // TODO : Duplicates?
}
@Override
public int getIndex() {
checkInitialized();
return index;
}
}
}