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