001    /*
002     * Copyright 2010-2016 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.kotlin.descriptors.impl;
018    
019    import kotlin.jvm.functions.Function0;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
023    import org.jetbrains.kotlin.descriptors.*;
024    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
025    import org.jetbrains.kotlin.name.Name;
026    import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
027    import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter;
028    import org.jetbrains.kotlin.resolve.scopes.MemberScope;
029    import org.jetbrains.kotlin.resolve.scopes.TypeIntersectionScope;
030    import org.jetbrains.kotlin.storage.NotNullLazyValue;
031    import org.jetbrains.kotlin.storage.StorageManager;
032    import org.jetbrains.kotlin.types.*;
033    
034    import java.util.Collection;
035    import java.util.Collections;
036    import java.util.List;
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<SimpleType> defaultType;
045    
046        protected AbstractTypeParameterDescriptor(
047                @NotNull final StorageManager storageManager,
048                @NotNull DeclarationDescriptor containingDeclaration,
049                @NotNull Annotations annotations,
050                @NotNull final Name name,
051                @NotNull Variance variance,
052                boolean isReified,
053                int index,
054                @NotNull SourceElement source,
055                @NotNull final SupertypeLoopChecker supertypeLoopChecker
056        ) {
057            super(containingDeclaration, annotations, name, source);
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 new TypeParameterTypeConstructor(storageManager, supertypeLoopChecker);
066                }
067            });
068            this.defaultType = storageManager.createLazyValue(new Function0<SimpleType>() {
069                @Override
070                public SimpleType invoke() {
071                    return KotlinTypeFactory.simpleType(
072                            Annotations.Companion.getEMPTY(),
073                            getTypeConstructor(), Collections.<TypeProjection>emptyList(), false,
074                            new LazyScopeAdapter(storageManager.createLazyValue(
075                                    new Function0<MemberScope>() {
076                                        @Override
077                                        public MemberScope invoke() {
078                                            return TypeIntersectionScope.create("Scope for type parameter " + name.asString(), getUpperBounds());
079                                        }
080                                    }
081                            ))
082                    );
083                }
084            });
085        }
086    
087        protected abstract void reportSupertypeLoopError(@NotNull KotlinType type);
088    
089        @NotNull
090        protected abstract List<KotlinType> resolveUpperBounds();
091    
092        @NotNull
093        @Override
094        public Variance getVariance() {
095            return variance;
096        }
097    
098        @Override
099        public boolean isReified() {
100            return reified;
101        }
102    
103        @Override
104        public int getIndex() {
105            return index;
106        }
107    
108        @Override
109        public boolean isCapturedFromOuterDeclaration() {
110            return false;
111        }
112    
113        @NotNull
114        @Override
115        public List<KotlinType> getUpperBounds() {
116            return ((TypeParameterTypeConstructor) getTypeConstructor()).getSupertypes();
117        }
118    
119        @NotNull
120        @Override
121        public final TypeConstructor getTypeConstructor() {
122            return typeConstructor.invoke();
123        }
124    
125        @NotNull
126        @Override
127        public SimpleType getDefaultType() {
128            return defaultType.invoke();
129        }
130    
131        @NotNull
132        @Override
133        public TypeParameterDescriptor getOriginal() {
134            return (TypeParameterDescriptor) super.getOriginal();
135        }
136    
137        @NotNull
138        @Override
139        @Deprecated
140        public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
141            throw new UnsupportedOperationException("Don't call substitute() on type parameters");
142        }
143    
144        @Override
145        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
146            return visitor.visitTypeParameterDescriptor(this, data);
147        }
148    
149        private class TypeParameterTypeConstructor extends AbstractTypeConstructor {
150    
151            private final SupertypeLoopChecker supertypeLoopChecker;
152    
153            public TypeParameterTypeConstructor(@NotNull StorageManager storageManager, SupertypeLoopChecker supertypeLoopChecker) {
154                super(storageManager);
155                this.supertypeLoopChecker = supertypeLoopChecker;
156            }
157    
158            @NotNull
159            @Override
160            protected Collection<KotlinType> computeSupertypes() {
161                return resolveUpperBounds();
162            }
163    
164            @NotNull
165            @Override
166            public List<TypeParameterDescriptor> getParameters() {
167                return Collections.emptyList();
168            }
169    
170            @Override
171            public boolean isFinal() {
172                return false;
173            }
174    
175            @Override
176            public boolean isDenotable() {
177                return true;
178            }
179    
180            @NotNull
181            @Override
182            public ClassifierDescriptor getDeclarationDescriptor() {
183                return AbstractTypeParameterDescriptor.this;
184            }
185    
186            @NotNull
187            @Override
188            public KotlinBuiltIns getBuiltIns() {
189                return DescriptorUtilsKt.getBuiltIns(AbstractTypeParameterDescriptor.this);
190            }
191    
192            @Override
193            public String toString() {
194                return getName().toString();
195            }
196    
197            @NotNull
198            @Override
199            protected SupertypeLoopChecker getSupertypeLoopChecker() {
200                return supertypeLoopChecker;
201            }
202    
203            @Override
204            protected void reportSupertypeLoopError(@NotNull KotlinType type) {
205                AbstractTypeParameterDescriptor.this.reportSupertypeLoopError(type);
206            }
207    
208            @Nullable
209            @Override
210            protected KotlinType defaultSupertypeIfEmpty() {
211                return ErrorUtils.createErrorType("Cyclic upper bounds");
212            }
213        }
214    }