/* * Copyright 2010-2016 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.kotlin.descriptors.impl; import kotlin.jvm.functions.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter; import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.TypeIntersectionScope; import org.jetbrains.kotlin.storage.NotNullLazyValue; import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.types.*; import java.util.Collection; import java.util.Collections; import java.util.List; 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<SimpleType> defaultType; protected AbstractTypeParameterDescriptor( @NotNull final StorageManager storageManager, @NotNull DeclarationDescriptor containingDeclaration, @NotNull Annotations annotations, @NotNull final Name name, @NotNull Variance variance, boolean isReified, int index, @NotNull SourceElement source, @NotNull final SupertypeLoopChecker supertypeLoopChecker ) { super(containingDeclaration, annotations, name, source); this.variance = variance; this.reified = isReified; this.index = index; this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() { @Override public TypeConstructor invoke() { return new TypeParameterTypeConstructor(storageManager, supertypeLoopChecker); } }); this.defaultType = storageManager.createLazyValue(new Function0<SimpleType>() { @Override public SimpleType invoke() { return KotlinTypeFactory.simpleType( Annotations.Companion.getEMPTY(), getTypeConstructor(), Collections.<TypeProjection>emptyList(), false, new LazyScopeAdapter(storageManager.createLazyValue( new Function0<MemberScope>() { @Override public MemberScope invoke() { return TypeIntersectionScope.create("Scope for type parameter " + name.asString(), getUpperBounds()); } } )) ); } }); } protected abstract void reportSupertypeLoopError(@NotNull KotlinType type); @NotNull protected abstract List<KotlinType> resolveUpperBounds(); @NotNull @Override public Variance getVariance() { return variance; } @Override public boolean isReified() { return reified; } @Override public int getIndex() { return index; } @Override public boolean isCapturedFromOuterDeclaration() { return false; } @NotNull @Override public List<KotlinType> getUpperBounds() { return ((TypeParameterTypeConstructor) getTypeConstructor()).getSupertypes(); } @NotNull @Override public final TypeConstructor getTypeConstructor() { return typeConstructor.invoke(); } @NotNull @Override public SimpleType getDefaultType() { return defaultType.invoke(); } @NotNull @Override public TypeParameterDescriptor getOriginal() { return (TypeParameterDescriptor) super.getOriginal(); } @Override public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) { return visitor.visitTypeParameterDescriptor(this, data); } private class TypeParameterTypeConstructor extends AbstractTypeConstructor { private final SupertypeLoopChecker supertypeLoopChecker; public TypeParameterTypeConstructor(@NotNull StorageManager storageManager, SupertypeLoopChecker supertypeLoopChecker) { super(storageManager); this.supertypeLoopChecker = supertypeLoopChecker; } @NotNull @Override protected Collection<KotlinType> computeSupertypes() { return resolveUpperBounds(); } @NotNull @Override public List<TypeParameterDescriptor> getParameters() { return Collections.emptyList(); } @Override public boolean isFinal() { return false; } @Override public boolean isDenotable() { return true; } @NotNull @Override public ClassifierDescriptor getDeclarationDescriptor() { return AbstractTypeParameterDescriptor.this; } @NotNull @Override public KotlinBuiltIns getBuiltIns() { return DescriptorUtilsKt.getBuiltIns(AbstractTypeParameterDescriptor.this); } @Override public String toString() { return getName().toString(); } @NotNull @Override protected SupertypeLoopChecker getSupertypeLoopChecker() { return supertypeLoopChecker; } @Override protected void reportSupertypeLoopError(@NotNull KotlinType type) { AbstractTypeParameterDescriptor.this.reportSupertypeLoopError(type); } @Nullable @Override protected KotlinType defaultSupertypeIfEmpty() { return ErrorUtils.createErrorType("Cyclic upper bounds"); } } }