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(@NotNull FunctionDescriptor functionDescriptor, List<JetType> typeArguments) { 057 if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap(); 058 059 Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>(); 060 061 int typeArgumentsSize = typeArguments.size(); 062 List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters(); 063 assert typeArgumentsSize == typeParameters.size(); 064 for (int i = 0; i < typeArgumentsSize; i++) { 065 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i); 066 JetType typeArgument = typeArguments.get(i); 067 result.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjectionImpl(typeArgument)); 068 } 069 return result; 070 } 071 072 @NotNull 073 public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) { 074 WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, new TraceBasedRedeclarationHandler(trace), "Function inner scope"); 075 ReceiverParameterDescriptor receiver = descriptor.getReceiverParameter(); 076 if (receiver != null) { 077 parameterScope.setImplicitReceiver(receiver); 078 } 079 for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) { 080 parameterScope.addTypeParameterDescriptor(typeParameter); 081 } 082 for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) { 083 parameterScope.addVariableDescriptor(valueParameterDescriptor); 084 } 085 parameterScope.addLabeledDeclaration(descriptor); 086 parameterScope.changeLockLevel(WritableScope.LockLevel.READING); 087 return parameterScope; 088 } 089 090 public static void initializeFromFunctionType( 091 @NotNull FunctionDescriptorImpl functionDescriptor, 092 @NotNull JetType functionType, 093 @Nullable ReceiverParameterDescriptor expectedThisObject, 094 @NotNull Modality modality, 095 @NotNull Visibility visibility 096 ) { 097 098 assert KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(functionType); 099 functionDescriptor.initialize(KotlinBuiltIns.getInstance().getReceiverType(functionType), 100 expectedThisObject, 101 Collections.<TypeParameterDescriptorImpl>emptyList(), 102 KotlinBuiltIns.getInstance().getValueParameters(functionDescriptor, functionType), 103 KotlinBuiltIns.getInstance().getReturnTypeFromFunctionType(functionType), 104 modality, 105 visibility); 106 } 107 108 public static <D extends CallableDescriptor> D alphaConvertTypeParameters(D candidate) { 109 return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH); 110 } 111 112 /** 113 * Returns function's copy with new parameter list. Note that parameters may belong to other methods or have incorrect "index" property 114 * -- it will be fixed by this function. 115 */ 116 @NotNull 117 public static FunctionDescriptor replaceFunctionParameters( 118 @NotNull FunctionDescriptor function, 119 @NotNull List<ValueParameterDescriptor> newParameters 120 ) { 121 FunctionDescriptorImpl descriptor = new SimpleFunctionDescriptorImpl( 122 function.getContainingDeclaration(), 123 function.getAnnotations(), 124 function.getName(), 125 function.getKind()); 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(new ValueParameterDescriptorImpl( 133 descriptor, 134 idx, 135 parameter.getAnnotations(), 136 parameter.getName(), 137 returnType, 138 parameter.declaresDefaultValue(), 139 parameter.getVarargElementType()) 140 ); 141 idx++; 142 } 143 ReceiverParameterDescriptor receiver = function.getReceiverParameter(); 144 descriptor.initialize( 145 receiver == null ? null : receiver.getType(), 146 function.getExpectedThisObject(), 147 function.getTypeParameters(), 148 parameters, 149 function.getReturnType(), 150 function.getModality(), 151 function.getVisibility()); 152 return descriptor; 153 } 154 }