/*
* 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.
simpleTypeWithNonTrivialMemberScope(
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");
}
}
}