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;
018
019 import kotlin.Unit;
020 import kotlin.jvm.functions.Function1;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
024 import org.jetbrains.kotlin.descriptors.*;
025 import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
026 import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
027 import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
028 import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
029 import org.jetbrains.kotlin.resolve.scopes.*;
030 import org.jetbrains.kotlin.types.*;
031 import org.jetbrains.kotlin.types.typeUtil.TypeUtilPackage;
032
033 import java.util.ArrayList;
034 import java.util.Collections;
035 import java.util.List;
036
037 public class FunctionDescriptorUtil {
038 private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitution() {
039
040 @Override
041 public TypeProjection get(@NotNull JetType key) {
042 return null;
043 }
044
045 @Override
046 public String toString() {
047 return "FunctionDescriptorUtil.MAKE_TYPE_PARAMETERS_FRESH";
048 }
049 });
050
051 private FunctionDescriptorUtil() {
052 }
053
054 public static TypeSubstitution createSubstitution(
055 @NotNull FunctionDescriptor functionDescriptor,
056 @NotNull List<JetType> typeArguments
057 ) {
058 if (functionDescriptor.getTypeParameters().isEmpty()) return TypeSubstitution.getEMPTY();
059
060 return new IndexedParametersSubstitution(functionDescriptor.getTypeParameters(), TypeUtilPackage.defaultProjections(typeArguments));
061 }
062
063 @NotNull
064 public static LexicalScope getFunctionInnerScope(@NotNull LexicalScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
065 TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace);
066 return getFunctionInnerScope(outerScope, descriptor, redeclarationHandler);
067 }
068
069 @NotNull
070 public static LexicalScope getFunctionInnerScope(
071 @NotNull LexicalScope outerScope,
072 @NotNull final FunctionDescriptor descriptor,
073 @NotNull RedeclarationHandler redeclarationHandler
074 ) {
075 ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter();
076 return new LexicalScopeImpl(outerScope, descriptor, true, receiver, "Function inner scope", redeclarationHandler,
077 new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
078 @Override
079 public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
080 for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
081 handler.addClassifierDescriptor(typeParameter);
082 }
083 for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
084 handler.addVariableDescriptor(valueParameterDescriptor);
085 }
086 return Unit.INSTANCE$;
087 }
088 });
089 }
090
091 public static void initializeFromFunctionType(
092 @NotNull FunctionDescriptorImpl functionDescriptor,
093 @NotNull JetType functionType,
094 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
095 @NotNull Modality modality,
096 @NotNull Visibility visibility
097 ) {
098
099 assert KotlinBuiltIns.isFunctionOrExtensionFunctionType(functionType);
100 functionDescriptor.initialize(KotlinBuiltIns.getReceiverType(functionType),
101 dispatchReceiverParameter,
102 Collections.<TypeParameterDescriptorImpl>emptyList(),
103 KotlinBuiltIns.getValueParameters(functionDescriptor, functionType),
104 KotlinBuiltIns.getReturnTypeFromFunctionType(functionType),
105 modality,
106 visibility);
107 }
108
109 public static <D extends CallableDescriptor> D alphaConvertTypeParameters(D candidate) {
110 return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH);
111 }
112
113 /**
114 * Returns function's copy with new parameter list. Note that parameters may belong to other methods or have incorrect "index" property
115 * -- it will be fixed by this function.
116 */
117 @NotNull
118 public static FunctionDescriptor replaceFunctionParameters(
119 @NotNull FunctionDescriptor function,
120 @NotNull List<ValueParameterDescriptor> newParameters
121 ) {
122 FunctionDescriptorImpl descriptor = SimpleFunctionDescriptorImpl.create(
123 function.getContainingDeclaration(),
124 function.getAnnotations(),
125 function.getName(),
126 function.getKind(),
127 SourceElement.NO_SOURCE
128 );
129 List<ValueParameterDescriptor> parameters = new ArrayList<ValueParameterDescriptor>(newParameters.size());
130 int idx = 0;
131 for (ValueParameterDescriptor parameter : newParameters) {
132 JetType returnType = parameter.getReturnType();
133 assert returnType != null;
134
135 parameters.add(
136 new ValueParameterDescriptorImpl(
137 descriptor,
138 null,
139 idx,
140 parameter.getAnnotations(),
141 parameter.getName(),
142 returnType,
143 parameter.declaresDefaultValue(),
144 parameter.getVarargElementType(),
145 SourceElement.NO_SOURCE
146 )
147 );
148 idx++;
149 }
150 ReceiverParameterDescriptor receiver = function.getExtensionReceiverParameter();
151 descriptor.initialize(
152 receiver == null ? null : receiver.getType(),
153 function.getDispatchReceiverParameter(),
154 function.getTypeParameters(),
155 parameters,
156 function.getReturnType(),
157 function.getModality(),
158 function.getVisibility());
159 return descriptor;
160 }
161 }