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