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.TypeUtilsKt; 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 KotlinType 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<KotlinType> typeArguments 057 ) { 058 if (functionDescriptor.getTypeParameters().isEmpty()) return TypeSubstitution.EMPTY; 059 060 return new IndexedParametersSubstitution(functionDescriptor.getTypeParameters(), TypeUtilsKt.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, LexicalScopeKind.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 KotlinType 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 KotlinType 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.isCrossinline(), 145 parameter.isNoinline(), 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 descriptor.setOperator(function.isOperator()); 162 descriptor.setInfix(function.isInfix()); 163 descriptor.setExternal(function.isExternal()); 164 descriptor.setInline(function.isInline()); 165 descriptor.setTailrec(function.isTailrec()); 166 return descriptor; 167 } 168 }