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