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.resolve.lazy;
018    
019    import com.intellij.openapi.diagnostic.Logger;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.kotlin.descriptors.*;
023    import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
024    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
025    import org.jetbrains.kotlin.resolve.DescriptorUtils;
026    import org.jetbrains.kotlin.resolve.scopes.MemberScope;
027    import org.jetbrains.kotlin.types.*;
028    
029    import java.util.Collection;
030    
031    public class ForceResolveUtil {
032        private static final Logger LOG = Logger.getInstance(ForceResolveUtil.class);
033    
034        private ForceResolveUtil() {}
035    
036        public static <T> T forceResolveAllContents(@NotNull T descriptor) {
037            doForceResolveAllContents(descriptor);
038            return descriptor;
039        }
040    
041        public static void forceResolveAllContents(@NotNull MemberScope scope) {
042            forceResolveAllContents(DescriptorUtils.getAllDescriptors(scope));
043        }
044    
045        public static void forceResolveAllContents(@NotNull Iterable<? extends DeclarationDescriptor> descriptors) {
046            for (DeclarationDescriptor descriptor : descriptors) {
047                forceResolveAllContents(descriptor);
048            }
049        }
050    
051        public static void forceResolveAllContents(@NotNull Collection<KotlinType> types) {
052            for (KotlinType type : types) {
053                forceResolveAllContents(type);
054            }
055        }
056    
057        public static void forceResolveAllContents(@NotNull TypeConstructor typeConstructor) {
058            doForceResolveAllContents(typeConstructor);
059        }
060    
061        public static void forceResolveAllContents(@NotNull Annotations annotations) {
062            doForceResolveAllContents(annotations);
063            for (AnnotationWithTarget annotationWithTarget : annotations.getAllAnnotations()) {
064                doForceResolveAllContents(annotationWithTarget.getAnnotation());
065            }
066        }
067    
068        private static void doForceResolveAllContents(Object object) {
069            if (object instanceof LazyEntity) {
070                LazyEntity lazyEntity = (LazyEntity) object;
071                lazyEntity.forceResolveAllContents();
072            }
073            else if (object instanceof CallableDescriptor) {
074                CallableDescriptor callableDescriptor = (CallableDescriptor) object;
075                ReceiverParameterDescriptor parameter = callableDescriptor.getExtensionReceiverParameter();
076                if (parameter != null) {
077                    forceResolveAllContents(parameter.getType());
078                }
079                for (ValueParameterDescriptor parameterDescriptor : callableDescriptor.getValueParameters()) {
080                    forceResolveAllContents(parameterDescriptor);
081                }
082                for (TypeParameterDescriptor typeParameterDescriptor : callableDescriptor.getTypeParameters()) {
083                    forceResolveAllContents(typeParameterDescriptor.getUpperBounds());
084                }
085                forceResolveAllContents(callableDescriptor.getReturnType());
086                forceResolveAllContents(callableDescriptor.getAnnotations());
087            }
088        }
089    
090        @Nullable
091        public static KotlinType forceResolveAllContents(@Nullable KotlinType type) {
092            if (type == null) return null;
093    
094            forceResolveAllContents(type.getAnnotations());
095            if (FlexibleTypesKt.isFlexible(type)) {
096                forceResolveAllContents(FlexibleTypesKt.flexibility(type).getLowerBound());
097                forceResolveAllContents(FlexibleTypesKt.flexibility(type).getUpperBound());
098            }
099            else {
100                forceResolveAllContents(type.getConstructor());
101                for (TypeProjection projection : type.getArguments()) {
102                    if (!projection.isStarProjection()) {
103                        forceResolveAllContents(projection.getType());
104                    }
105                }
106            }
107            return type;
108        }
109    }