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