001 /*
002 * Copyright 2010-2014 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.lang.descriptors.impl;
018
019 import kotlin.Function0;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.ReadOnly;
022 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
023 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
024 import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
025 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
026 import org.jetbrains.jet.lang.resolve.name.Name;
027 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
028 import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
029 import org.jetbrains.jet.lang.types.*;
030 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
031 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
032 import org.jetbrains.jet.storage.NotNullLazyValue;
033 import org.jetbrains.jet.storage.StorageManager;
034
035 import java.util.Collections;
036 import java.util.Set;
037
038 public abstract class AbstractTypeParameterDescriptor extends DeclarationDescriptorNonRootImpl implements TypeParameterDescriptor {
039 private final Variance variance;
040 private final boolean reified;
041 private final int index;
042
043 private final NotNullLazyValue<TypeConstructor> typeConstructor;
044 private final NotNullLazyValue<JetType> defaultType;
045 private final NotNullLazyValue<Set<JetType>> upperBounds;
046 private final NotNullLazyValue<JetType> upperBoundsAsType;
047
048 protected AbstractTypeParameterDescriptor(
049 @NotNull final StorageManager storageManager,
050 @NotNull DeclarationDescriptor containingDeclaration,
051 @NotNull Annotations annotations,
052 @NotNull Name name,
053 @NotNull Variance variance,
054 boolean isReified,
055 int index
056 ) {
057 super(containingDeclaration, annotations, name);
058 this.variance = variance;
059 this.reified = isReified;
060 this.index = index;
061
062 this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
063 @Override
064 public TypeConstructor invoke() {
065 return createTypeConstructor();
066 }
067 });
068 this.defaultType = storageManager.createLazyValue(new Function0<JetType>() {
069 @Override
070 public JetType invoke() {
071 return new JetTypeImpl(Annotations.EMPTY, getTypeConstructor(), false, Collections.<TypeProjection>emptyList(),
072 new LazyScopeAdapter(storageManager.createLazyValue(
073 new Function0<JetScope>() {
074 @Override
075 public JetScope invoke() {
076 return getUpperBoundsAsType().getMemberScope();
077 }
078 }
079 )));
080 }
081 });
082 this.upperBounds = storageManager.createLazyValue(new Function0<Set<JetType>>() {
083 @Override
084 public Set<JetType> invoke() {
085 return resolveUpperBounds();
086 }
087 });
088 this.upperBoundsAsType = storageManager.createLazyValue(new Function0<JetType>() {
089 @Override
090 public JetType invoke() {
091 return computeUpperBoundsAsType();
092 }
093 });
094 }
095
096 @NotNull
097 @ReadOnly
098 protected abstract Set<JetType> resolveUpperBounds();
099
100 @NotNull
101 protected abstract TypeConstructor createTypeConstructor();
102
103 @NotNull
104 @Override
105 public Variance getVariance() {
106 return variance;
107 }
108
109 @Override
110 public boolean isReified() {
111 return reified;
112 }
113
114 @Override
115 public int getIndex() {
116 return index;
117 }
118
119 @NotNull
120 @Override
121 public Set<JetType> getUpperBounds() {
122 return upperBounds.invoke();
123 }
124
125 @NotNull
126 @Override
127 public JetType getUpperBoundsAsType() {
128 return upperBoundsAsType.invoke();
129 }
130
131 @NotNull
132 private JetType computeUpperBoundsAsType() {
133 Set<JetType> upperBounds = getUpperBounds();
134 assert !upperBounds.isEmpty() : "Upper bound list is empty in " + getName();
135 JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
136 return upperBoundsAsType != null ? upperBoundsAsType : KotlinBuiltIns.getInstance().getNothingType();
137 }
138
139 @NotNull
140 @Override
141 public TypeConstructor getTypeConstructor() {
142 return typeConstructor.invoke();
143 }
144
145 @NotNull
146 @Override
147 public JetType getDefaultType() {
148 return defaultType.invoke();
149 }
150
151 @Override
152 public JetType getClassObjectType() {
153 // TODO: class object bounds
154 return null;
155 }
156
157 @NotNull
158 @Override
159 public Set<JetType> getLowerBounds() {
160 return Collections.singleton(KotlinBuiltIns.getInstance().getNothingType());
161 }
162
163 @NotNull
164 @Override
165 @Deprecated
166 public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
167 throw new UnsupportedOperationException("Don't call substitute() on type parameters");
168 }
169
170 @Override
171 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
172 return visitor.visitTypeParameterDescriptor(this, data);
173 }
174 }