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;
018    
019    import kotlin.Unit;
020    import kotlin.jvm.functions.Function1;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.kotlin.descriptors.*;
023    import org.jetbrains.kotlin.resolve.scopes.*;
024    import org.jetbrains.kotlin.types.*;
025    import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
026    
027    import java.util.List;
028    
029    public class FunctionDescriptorUtil {
030        private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitution() {
031            @Override
032            public TypeProjection get(@NotNull KotlinType key) {
033                return null;
034            }
035    
036            @Override
037            public String toString() {
038                return "FunctionDescriptorUtil.MAKE_TYPE_PARAMETERS_FRESH";
039            }
040        });
041    
042        private FunctionDescriptorUtil() {
043        }
044    
045        public static TypeSubstitution createSubstitution(
046                @NotNull FunctionDescriptor functionDescriptor,
047                @NotNull List<KotlinType> typeArguments
048        ) {
049            if (functionDescriptor.getTypeParameters().isEmpty()) return TypeSubstitution.EMPTY;
050    
051            return new IndexedParametersSubstitution(functionDescriptor.getTypeParameters(), TypeUtilsKt.defaultProjections(typeArguments));
052        }
053    
054        @NotNull
055        public static LexicalScope getFunctionInnerScope(
056                @NotNull LexicalScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace
057        ) {
058            return getFunctionInnerScope(outerScope, descriptor, new TraceBasedLocalRedeclarationChecker(trace));
059        }
060    
061        @NotNull
062        public static LexicalScope getFunctionInnerScope(
063                @NotNull LexicalScope outerScope,
064                @NotNull final FunctionDescriptor descriptor,
065                @NotNull LocalRedeclarationChecker redeclarationChecker
066        ) {
067            ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter();
068            return new LexicalScopeImpl(outerScope, descriptor, true, receiver, LexicalScopeKind.FUNCTION_INNER_SCOPE, redeclarationChecker,
069                                        new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
070                                            @Override
071                                            public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
072                                                for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
073                                                    handler.addClassifierDescriptor(typeParameter);
074                                                }
075                                                for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
076                                                    handler.addVariableDescriptor(valueParameterDescriptor);
077                                                }
078                                                return Unit.INSTANCE;
079                                            }
080                                        });
081        }
082    
083        @SuppressWarnings("unchecked")
084        public static <D extends CallableDescriptor> D alphaConvertTypeParameters(D candidate) {
085            return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH);
086        }
087    }