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