diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyTypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyTypeParameterDescriptor.java new file mode 100644 index 00000000000..a840a56ec42 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyTypeParameterDescriptor.java @@ -0,0 +1,262 @@ +/* + * Copyright 2010-2013 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.resolve.lazy.descriptors; + +import com.intellij.openapi.util.Computable; +import org.jetbrains.annotations.NotNull; +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.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.lazy.storage.NotNullLazyValue; +import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager; +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.util.lazy.RecursionIntolerantLazyValue; + +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; + private final NotNullLazyValue defaultType; + private final NotNullLazyValue> upperBounds; + private final NotNullLazyValue upperBoundsAsType; + + public AbstractLazyTypeParameterDescriptor( + @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 Computable() { + @Override + public TypeConstructor compute() { + return createTypeConstructor(); + } + }); + this.defaultType = storageManager.createLazyValue(new Computable() { + @Override + public JetType compute() { + return createDefaultType(); + } + }); + this.upperBounds = storageManager.createLazyValue(new Computable>() { + @Override + public Set compute() { + return resolveUpperBounds(); + } + }); + this.upperBoundsAsType = storageManager.createLazyValue(new Computable() { + @Override + public JetType compute() { + return computeUpperBoundsAsType(); + } + }); + } + + @Override + public boolean isReified() { + return reified; + } + + @Override + public Variance getVariance() { + return variance; + } + + @NotNull + @Override + public Set getUpperBounds() { + return upperBounds.compute(); + } + + @NotNull + protected abstract Set resolveUpperBounds(); + + @NotNull + @Override + public JetType getUpperBoundsAsType() { + return upperBoundsAsType.compute(); + } + + @NotNull + private JetType computeUpperBoundsAsType() { + Set 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 getLowerBounds() { + return Collections.singleton(getLowerBoundsAsType()); + } + + @NotNull + @Override + public JetType getLowerBoundsAsType() { + return KotlinBuiltIns.getInstance().getNothingType(); + } + + @NotNull + @Override + public TypeConstructor getTypeConstructor() { + return typeConstructor.compute(); + } + + @NotNull + private TypeConstructor createTypeConstructor() { + return new TypeConstructor() { + @NotNull + @Override + public Collection getSupertypes() { + return AbstractLazyTypeParameterDescriptor.this.getUpperBounds(); + } + + @NotNull + @Override + public List getParameters() { + return Collections.emptyList(); + } + + @Override + public boolean isSealed() { + return false; + } + + @Override + public ClassifierDescriptor getDeclarationDescriptor() { + return AbstractLazyTypeParameterDescriptor.this; + } + + @Override + public List getAnnotations() { + return AbstractLazyTypeParameterDescriptor.this.getAnnotations(); + } + + @Override + public String toString() { + return getName().toString(); + } + }; + } + + @NotNull + @Override + public JetType getDefaultType() { + return defaultType.compute(); + } + + @NotNull + private JetType createDefaultType() { + return new JetTypeImpl(getTypeConstructor(), new LazyScopeAdapter(new RecursionIntolerantLazyValue() { + @Override + protected JetScope compute() { + 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 accept(DeclarationDescriptorVisitor visitor, D data) { + return visitor.visitTypeParameterDescriptor(this, data); + } + + @Override + public void acceptVoid(DeclarationDescriptorVisitor visitor) { + visitor.visitTypeParameterDescriptor(this, null); + } + + @Override + public int getIndex() { + return index; + } + + @Override + public List getAnnotations() { + return Collections.emptyList(); // 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); + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java index 59ae4e5c007..e62df9b6372 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java @@ -17,111 +17,47 @@ package org.jetbrains.jet.lang.resolve.lazy.descriptors; import com.google.common.collect.Sets; -import com.intellij.openapi.util.Computable; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -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.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.lazy.LazyDescriptor; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; -import org.jetbrains.jet.lang.resolve.lazy.storage.NotNullLazyValue; -import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager; -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.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue; -import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Set; -public class LazyTypeParameterDescriptor implements TypeParameterDescriptor, LazyDescriptor { +public class LazyTypeParameterDescriptor extends AbstractLazyTypeParameterDescriptor implements TypeParameterDescriptor, LazyDescriptor { private final ResolveSession resolveSession; private final JetTypeParameter jetTypeParameter; - private final Variance variance; - private final boolean reified; - private final int index; - private final LazyClassDescriptor containingDeclaration; - private final Name name; - - private final NotNullLazyValue typeConstructor; - private final NotNullLazyValue defaultType; - private final NotNullLazyValue> upperBounds; - private final NotNullLazyValue upperBoundsAsType; public LazyTypeParameterDescriptor( @NotNull ResolveSession resolveSession, @NotNull LazyClassDescriptor containingDeclaration, @NotNull JetTypeParameter jetTypeParameter, int index) { + super( + resolveSession.getStorageManager(), + containingDeclaration, + ResolveSessionUtils.safeNameForLazyResolve(jetTypeParameter.getNameAsName()), + jetTypeParameter.getVariance(), + jetTypeParameter.hasModifier(JetTokens.REIFIED_KEYWORD), + index + ); this.resolveSession = resolveSession; this.jetTypeParameter = jetTypeParameter; - this.variance = jetTypeParameter.getVariance(); - this.containingDeclaration = containingDeclaration; - this.index = index; - this.name = ResolveSessionUtils.safeNameForLazyResolve(jetTypeParameter.getNameAsName()); this.resolveSession.getTrace().record(BindingContext.TYPE_PARAMETER, jetTypeParameter, this); - - this.reified = jetTypeParameter.hasModifier(JetTokens.REIFIED_KEYWORD); - - StorageManager storageManager = resolveSession.getStorageManager(); - this.typeConstructor = storageManager.createLazyValue(new Computable() { - @Override - public TypeConstructor compute() { - return createTypeConstructor(); - } - }); - this.defaultType = storageManager.createLazyValue(new Computable() { - @Override - public JetType compute() { - return createDefaultType(); - } - }); - this.upperBounds = storageManager.createLazyValue(new Computable>() { - @Override - public Set compute() { - return resolveUpperBounds(); - } - }); - this.upperBoundsAsType = storageManager.createLazyValue(new Computable() { - @Override - public JetType compute() { - return computeUpperBoundsAsType(); - } - }); - } - - @Override - public boolean isReified() { - return reified; - } - - @Override - public Variance getVariance() { - return variance; } @NotNull @Override - public Set getUpperBounds() { - return upperBounds.compute(); - } - - @NotNull - private Set resolveUpperBounds() { + protected Set resolveUpperBounds() { Set upperBounds = Sets.newLinkedHashSet(); JetTypeParameter jetTypeParameter = this.jetTypeParameter; @@ -149,7 +85,7 @@ public class LazyTypeParameterDescriptor implements TypeParameterDescriptor, Laz JetSimpleNameExpression constrainedParameterName = jetTypeConstraint.getSubjectTypeParameterName(); if (constrainedParameterName != null) { - if (name.equals(constrainedParameterName.getReferencedNameAsName())) { + if (getName().equals(constrainedParameterName.getReferencedNameAsName())) { JetTypeReference boundTypeReference = jetTypeConstraint.getBoundTypeReference(); if (boundTypeReference != null) { @@ -164,151 +100,14 @@ public class LazyTypeParameterDescriptor implements TypeParameterDescriptor, Laz private JetType resolveBoundType(@NotNull JetTypeReference boundTypeReference) { return resolveSession.getInjector().getTypeResolver() - .resolveType(containingDeclaration.getScopeForClassHeaderResolution(), boundTypeReference, + .resolveType(getContainingDeclaration().getScopeForClassHeaderResolution(), boundTypeReference, resolveSession.getTrace(), false); } @NotNull @Override - public JetType getUpperBoundsAsType() { - return upperBoundsAsType.compute(); - } - - @NotNull - private JetType computeUpperBoundsAsType() { - Set 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 getLowerBounds() { - return Collections.singleton(getLowerBoundsAsType()); - } - - @NotNull - @Override - public JetType getLowerBoundsAsType() { - return KotlinBuiltIns.getInstance().getNothingType(); - } - - @NotNull - @Override - public TypeConstructor getTypeConstructor() { - return typeConstructor.compute(); - } - - @NotNull - private TypeConstructor createTypeConstructor() { - return new TypeConstructor() { - @NotNull - @Override - public Collection getSupertypes() { - return LazyTypeParameterDescriptor.this.getUpperBounds(); - } - - @NotNull - @Override - public List getParameters() { - return Collections.emptyList(); - } - - @Override - public boolean isSealed() { - return false; - } - - @Override - public ClassifierDescriptor getDeclarationDescriptor() { - return LazyTypeParameterDescriptor.this; - } - - @Override - public List getAnnotations() { - return LazyTypeParameterDescriptor.this.getAnnotations(); - } - - @Override - public String toString() { - return getName().toString(); - } - }; - } - - @NotNull - @Override - public JetType getDefaultType() { - return defaultType.compute(); - } - - @NotNull - private JetType createDefaultType() { - return new JetTypeImpl(getTypeConstructor(), new LazyScopeAdapter(new RecursionIntolerantLazyValue() { - @Override - protected JetScope compute() { - 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 accept(DeclarationDescriptorVisitor visitor, D data) { - return visitor.visitTypeParameterDescriptor(this, data); - } - - @Override - public void acceptVoid(DeclarationDescriptorVisitor visitor) { - visitor.visitTypeParameterDescriptor(this, null); - } - - @Override - public int getIndex() { - return index; - } - - @Override - public List getAnnotations() { - return Collections.emptyList(); // TODO - } - - @NotNull - @Override - public Name getName() { - return name; - } - - @Override - public String toString() { - return getName().toString(); + public LazyClassDescriptor getContainingDeclaration() { + return (LazyClassDescriptor) super.getContainingDeclaration(); } @Override