001    /*
002     * Copyright 2010-2015 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.Unit;
020    import kotlin.jvm.functions.Function0;
021    import kotlin.jvm.functions.Function1;
022    import org.jetbrains.annotations.NotNull;
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.scopes.LazyScopeAdapter;
027    import org.jetbrains.kotlin.resolve.scopes.MemberScope;
028    import org.jetbrains.kotlin.resolve.scopes.TypeIntersectionScope;
029    import org.jetbrains.kotlin.storage.NotNullLazyValue;
030    import org.jetbrains.kotlin.storage.StorageManager;
031    import org.jetbrains.kotlin.types.*;
032    
033    import java.util.Collections;
034    import java.util.List;
035    
036    import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getBuiltIns;
037    
038    public abstract class AbstractTypeParameterDescriptor extends DeclarationDescriptorNonRootImpl implements TypeParameterDescriptor {
039        public static final List<KotlinType> FALLBACK_UPPER_BOUNDS_ON_RECURSION =
040                Collections.singletonList(ErrorUtils.createErrorType("Recursion while calculating upper bounds"));
041    
042        private final Variance variance;
043        private final boolean reified;
044        private final int index;
045    
046        private final NotNullLazyValue<TypeConstructor> typeConstructor;
047        private final NotNullLazyValue<KotlinType> defaultType;
048        private final NotNullLazyValue<List<KotlinType>> upperBounds;
049    
050        protected AbstractTypeParameterDescriptor(
051                @NotNull final StorageManager storageManager,
052                @NotNull DeclarationDescriptor containingDeclaration,
053                @NotNull Annotations annotations,
054                @NotNull final Name name,
055                @NotNull Variance variance,
056                boolean isReified,
057                int index,
058                @NotNull SourceElement source
059        ) {
060            super(containingDeclaration, annotations, name, source);
061            this.variance = variance;
062            this.reified = isReified;
063            this.index = index;
064    
065            this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
066                @Override
067                public TypeConstructor invoke() {
068                    return createTypeConstructor();
069                }
070            });
071            this.defaultType = storageManager.createLazyValue(new Function0<KotlinType>() {
072                @Override
073                public KotlinType invoke() {
074                    return KotlinTypeImpl.create(
075                            Annotations.Companion.getEMPTY(),
076                            getTypeConstructor(), false, Collections.<TypeProjection>emptyList(),
077                            new LazyScopeAdapter(storageManager.createLazyValue(
078                                    new Function0<MemberScope>() {
079                                        @Override
080                                        public MemberScope invoke() {
081                                            return TypeIntersectionScope.create("Scope for type parameter " + name.asString(), getUpperBounds());
082                                        }
083                                    }
084                            ))
085                    );
086                }
087            });
088            this.upperBounds = storageManager.createLazyValueWithPostCompute(
089                    new Function0<List<KotlinType>>() {
090                        @Override
091                        public List<KotlinType> invoke() {
092                            return resolveUpperBounds();
093                        }
094                    },
095                    new Function1<Boolean, List<KotlinType>>() {
096                        @Override
097                        public List<KotlinType> invoke(Boolean aBoolean) {
098                            return FALLBACK_UPPER_BOUNDS_ON_RECURSION;
099                        }
100                    },
101                    new Function1<List<KotlinType>, Unit>() {
102                        @Override
103                        public Unit invoke(List<KotlinType> types) {
104                            getSupertypeLoopChecker().findLoopsInSupertypesAndDisconnect(
105                                    getTypeConstructor(),
106                                    types,
107                                    new Function1<TypeConstructor, Iterable<? extends KotlinType>>() {
108                                        @Override
109                                        public Iterable<? extends KotlinType> invoke(TypeConstructor typeConstructor) {
110                                            if (typeConstructor.getDeclarationDescriptor() instanceof AbstractTypeParameterDescriptor) {
111                                                return ((AbstractTypeParameterDescriptor) typeConstructor.getDeclarationDescriptor())
112                                                        .resolveUpperBounds();
113                                            }
114                                            return typeConstructor.getSupertypes();
115                                        }
116                                    },
117                                    new Function1<KotlinType, Unit>() {
118                                        @Override
119                                        public Unit invoke(KotlinType type) {
120                                            reportCycleError(type);
121                                            return Unit.INSTANCE;
122                                        }
123                                    }
124                            );
125    
126                            if (types.isEmpty()) {
127                                types.add(ErrorUtils.createErrorType("Cyclic upper bounds"));
128                            }
129    
130                            return null;
131                        }
132                    });
133        }
134    
135        @NotNull
136        protected abstract SupertypeLoopChecker getSupertypeLoopChecker();
137        protected abstract void reportCycleError(@NotNull KotlinType type);
138    
139        @NotNull
140        protected abstract List<KotlinType> resolveUpperBounds();
141    
142        @NotNull
143        protected abstract TypeConstructor createTypeConstructor();
144    
145        @NotNull
146        @Override
147        public Variance getVariance() {
148            return variance;
149        }
150    
151        @Override
152        public boolean isReified() {
153            return reified;
154        }
155    
156        @Override
157        public int getIndex() {
158            return index;
159        }
160    
161        @Override
162        public boolean isCapturedFromOuterDeclaration() {
163            return false;
164        }
165    
166        @NotNull
167        @Override
168        public List<KotlinType> getUpperBounds() {
169            return upperBounds.invoke();
170        }
171    
172        @NotNull
173        @Override
174        public TypeConstructor getTypeConstructor() {
175            return typeConstructor.invoke();
176        }
177    
178        @NotNull
179        @Override
180        public KotlinType getDefaultType() {
181            return defaultType.invoke();
182        }
183    
184        @NotNull
185        @Override
186        public List<KotlinType> getLowerBounds() {
187            return Collections.singletonList(getBuiltIns(this).getNothingType());
188        }
189    
190        @NotNull
191        @Override
192        @Deprecated
193        public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
194            throw new UnsupportedOperationException("Don't call substitute() on type parameters");
195        }
196    
197        @Override
198        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
199            return visitor.visitTypeParameterDescriptor(this, data);
200        }
201    }