@Nullable public static List<ValueParameterDescriptor> getSubstitutedValueParameters( FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) { List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(); List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); // TODO : Lazy? JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); JetType varargElementType = unsubstitutedValueParameter.getVarargElementType(); JetType substituteVarargElementType = varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE); if (substitutedType == null) return null; result.add( new ValueParameterDescriptorImpl( substitutedDescriptor, unsubstitutedValueParameter, unsubstitutedValueParameter.getAnnotations(), unsubstitutedValueParameter.isVar(), substitutedType, substituteVarargElementType)); } return result; }
private TypeSubstitutor createTypeSubstitutorWithDefaultForUnknownTypeParameter( @Nullable final TypeProjection defaultTypeProjection) { return TypeSubstitutor.create( new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor(); if (declarationDescriptor instanceof TypeParameterDescriptor) { TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor; JetType value = ConstraintsUtil.getValue(getTypeConstraints(descriptor)); if (value != null && !TypeUtils.dependsOnTypeParameterConstructors( value, Collections.singleton(DONT_CARE.getConstructor()))) { return new TypeProjection(value); } if (typeParameterConstraints.containsKey(descriptor)) { return defaultTypeProjection; } } return null; } @Override public boolean isEmpty() { return false; } @Override public String toString() { return typeParameterConstraints.toString(); } }); }
@Nullable public static FunctionDescriptor substituteFunctionDescriptor( @NotNull List<JetType> typeArguments, @NotNull FunctionDescriptor functionDescriptor) { Map<TypeConstructor, TypeProjection> substitutionContext = createSubstitutionContext(functionDescriptor, typeArguments); return functionDescriptor.substitute(TypeSubstitutor.create(substitutionContext)); }
@Nullable public static KotlinType createSubstitutedSupertype( @NotNull KotlinType subType, @NotNull KotlinType superType, @NotNull TypeSubstitutor substitutor) { KotlinType substitutedType = substitutor.substitute(superType, Variance.INVARIANT); if (substitutedType != null) { return makeNullableIfNeeded(substitutedType, subType.isMarkedNullable()); } return null; }
@NotNull public static List<KotlinType> getImmediateSupertypes(@NotNull KotlinType type) { TypeSubstitutor substitutor = TypeSubstitutor.create(type); Collection<KotlinType> originalSupertypes = type.getConstructor().getSupertypes(); List<KotlinType> result = new ArrayList<KotlinType>(originalSupertypes.size()); for (KotlinType supertype : originalSupertypes) { KotlinType substitutedType = createSubstitutedSupertype(type, supertype, substitutor); if (substitutedType != null) { result.add(substitutedType); } } return result; }
@NotNull private static FunctionDescriptor substituteSuperFunction( @NotNull Map<ClassDescriptor, JetType> superclassToSupertype, @NotNull FunctionDescriptor superFun) { DeclarationDescriptor superFunContainer = superFun.getContainingDeclaration(); assert superFunContainer instanceof ClassDescriptor : superFunContainer; JetType supertype = superclassToSupertype.get(superFunContainer); assert supertype != null : "Couldn't find super type for super function: " + superFun; TypeSubstitutor supertypeSubstitutor = TypeSubstitutor.create(supertype); FunctionDescriptor substitutedSuperFun = superFun.substitute(supertypeSubstitutor); assert substitutedSuperFun != null; return substitutedSuperFun; }
@NotNull public static KotlinType substituteProjectionsForParameters( @NotNull ClassDescriptor clazz, @NotNull List<TypeProjection> projections) { List<TypeParameterDescriptor> clazzTypeParameters = clazz.getTypeConstructor().getParameters(); if (clazzTypeParameters.size() != projections.size()) { throw new IllegalArgumentException( "type parameter counts do not match: " + clazz + ", " + projections); } Map<TypeConstructor, TypeProjection> substitutions = org.jetbrains.kotlin.utils.CollectionsKt.newHashMapWithExpectedSize( clazzTypeParameters.size()); for (int i = 0; i < clazzTypeParameters.size(); ++i) { TypeConstructor typeConstructor = clazzTypeParameters.get(i).getTypeConstructor(); substitutions.put(typeConstructor, projections.get(i)); } return TypeSubstitutor.create(substitutions) .substitute(clazz.getDefaultType(), Variance.INVARIANT); }
public class FunctionDescriptorUtil { private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create( new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { return null; } @Override public boolean isEmpty() { return false; } @Override public String toString() { return "FunctionDescriptorUtil.MAKE_TYPE_PARAMETERS_FRESH"; } }); public static Map<TypeConstructor, TypeProjection> createSubstitutionContext( @NotNull FunctionDescriptor functionDescriptor, List<JetType> typeArguments) { if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap(); Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>(); int typeArgumentsSize = typeArguments.size(); List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters(); assert typeArgumentsSize == typeParameters.size(); for (int i = 0; i < typeArgumentsSize; i++) { TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i); JetType typeArgument = typeArguments.get(i); result.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjection(typeArgument)); } return result; } @Nullable public static List<ValueParameterDescriptor> getSubstitutedValueParameters( FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) { List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(); List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); // TODO : Lazy? JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); JetType varargElementType = unsubstitutedValueParameter.getVarargElementType(); JetType substituteVarargElementType = varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE); if (substitutedType == null) return null; result.add( new ValueParameterDescriptorImpl( substitutedDescriptor, unsubstitutedValueParameter, unsubstitutedValueParameter.getAnnotations(), unsubstitutedValueParameter.isVar(), substitutedType, substituteVarargElementType)); } return result; } @Nullable public static JetType getSubstitutedReturnType( @NotNull FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) { return substitutor.substitute(functionDescriptor.getReturnType(), Variance.OUT_VARIANCE); } @Nullable public static FunctionDescriptor substituteFunctionDescriptor( @NotNull List<JetType> typeArguments, @NotNull FunctionDescriptor functionDescriptor) { Map<TypeConstructor, TypeProjection> substitutionContext = createSubstitutionContext(functionDescriptor, typeArguments); return functionDescriptor.substitute(TypeSubstitutor.create(substitutionContext)); } @NotNull public static JetScope getFunctionInnerScope( @NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) { WritableScope parameterScope = new WritableScopeImpl( outerScope, descriptor, new TraceBasedRedeclarationHandler(trace), "Function inner scope"); ReceiverParameterDescriptor receiver = descriptor.getReceiverParameter(); if (receiver != null) { parameterScope.setImplicitReceiver(receiver); } for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) { parameterScope.addTypeParameterDescriptor(typeParameter); } for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) { parameterScope.addVariableDescriptor(valueParameterDescriptor); } parameterScope.addLabeledDeclaration(descriptor); parameterScope.changeLockLevel(WritableScope.LockLevel.READING); return parameterScope; } public static void initializeFromFunctionType( @NotNull FunctionDescriptorImpl functionDescriptor, @NotNull JetType functionType, @Nullable ReceiverParameterDescriptor expectedThisObject, @NotNull Modality modality, @NotNull Visibility visibility) { assert KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(functionType); functionDescriptor.initialize( KotlinBuiltIns.getInstance().getReceiverType(functionType), expectedThisObject, Collections.<TypeParameterDescriptorImpl>emptyList(), KotlinBuiltIns.getInstance().getValueParameters(functionDescriptor, functionType), KotlinBuiltIns.getInstance().getReturnTypeFromFunctionType(functionType), modality, visibility); } public static <D extends CallableDescriptor> D alphaConvertTypeParameters(D candidate) { return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH); } public static FunctionDescriptor getInvokeFunction(@NotNull JetType functionType) { assert KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(functionType); ClassifierDescriptor classDescriptorForFunction = functionType.getConstructor().getDeclarationDescriptor(); assert classDescriptorForFunction instanceof ClassDescriptor; Collection<FunctionDescriptor> invokeFunctions = ((ClassDescriptor) classDescriptorForFunction) .getMemberScope(functionType.getArguments()) .getFunctions(Name.identifier("invoke")); assert invokeFunctions.size() == 1; return invokeFunctions.iterator().next(); } }
@Nullable public static JetType getSubstitutedReturnType( @NotNull FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) { return substitutor.substitute(functionDescriptor.getReturnType(), Variance.OUT_VARIANCE); }