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.codegen;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.jet.lang.descriptors.*;
021 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
022 import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
023 import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor;
024 import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
025 import org.jetbrains.jet.lang.reflect.ReflectionTypes;
026 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
027 import org.jetbrains.jet.lang.resolve.ImportPath;
028 import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
029 import org.jetbrains.jet.lang.resolve.name.FqName;
030 import org.jetbrains.jet.lang.resolve.name.Name;
031 import org.jetbrains.jet.lang.types.*;
032 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
033
034 import java.util.*;
035
036 public class JvmFunctionImplTypes {
037 private final ReflectionTypes reflectionTypes;
038
039 private final ClassDescriptor functionImpl;
040 private final ClassDescriptor extensionFunctionImpl;
041 private final ClassDescriptor kFunctionImpl;
042 private final ClassDescriptor kMemberFunctionImpl;
043 private final ClassDescriptor kExtensionFunctionImpl;
044
045 public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) {
046 this.reflectionTypes = reflectionTypes;
047
048 ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
049 Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance());
050
051 PackageFragmentDescriptor kotlinJvmInternal =
052 new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal"));
053 PackageFragmentDescriptor kotlinReflectJvmInternal =
054 new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.reflect.jvm.internal"));
055
056 this.functionImpl = createClass(kotlinJvmInternal, "FunctionImpl", "out R");
057 this.extensionFunctionImpl = createClass(kotlinJvmInternal, "ExtensionFunctionImpl", "in T", "out R");
058 this.kFunctionImpl = createClass(kotlinReflectJvmInternal, "KFunctionImpl", "out R");
059 this.kExtensionFunctionImpl = createClass(kotlinReflectJvmInternal, "KExtensionFunctionImpl", "in T", "out R");
060 this.kMemberFunctionImpl = createClass(kotlinReflectJvmInternal, "KMemberFunctionImpl", "in T", "out R");
061 }
062
063 @NotNull
064 private static ClassDescriptor createClass(
065 @NotNull PackageFragmentDescriptor packageFragment,
066 @NotNull String name,
067 @NotNull String... typeParameters
068 ) {
069 MutableClassDescriptor descriptor = new MutableClassDescriptor(packageFragment, packageFragment.getMemberScope(),
070 ClassKind.CLASS, false, Name.identifier(name));
071 List<TypeParameterDescriptor> typeParameterDescriptors = new ArrayList<TypeParameterDescriptor>(typeParameters.length);
072 for (int i = 0; i < typeParameters.length; i++) {
073 String[] s = typeParameters[i].split(" ");
074 Variance variance = Variance.valueOf(s[0].toUpperCase() + "_VARIANCE");
075 String typeParameterName = s[1];
076 TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
077 descriptor, Annotations.EMPTY, false, variance, Name.identifier(typeParameterName), i
078 );
079 typeParameter.setInitialized();
080 typeParameterDescriptors.add(typeParameter);
081 }
082
083 descriptor.setModality(Modality.FINAL);
084 descriptor.setVisibility(Visibilities.PUBLIC);
085 descriptor.setTypeParameterDescriptors(typeParameterDescriptors);
086 descriptor.createTypeConstructor();
087
088 return descriptor;
089 }
090
091 @NotNull
092 public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
093 ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
094
095 List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2);
096
097 ClassDescriptor classDescriptor;
098 if (receiverParameter != null) {
099 classDescriptor = extensionFunctionImpl;
100 typeArguments.add(new TypeProjectionImpl(receiverParameter.getType()));
101 }
102 else {
103 classDescriptor = functionImpl;
104 }
105
106 //noinspection ConstantConditions
107 typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType()));
108
109 JetType functionImplType = new JetTypeImpl(
110 classDescriptor.getDefaultType().getAnnotations(),
111 classDescriptor.getTypeConstructor(),
112 false,
113 typeArguments,
114 classDescriptor.getMemberScope(typeArguments)
115 );
116
117 JetType functionType = KotlinBuiltIns.getInstance().getFunctionType(
118 Annotations.EMPTY,
119 receiverParameter == null ? null : receiverParameter.getType(),
120 DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()),
121 descriptor.getReturnType()
122 );
123
124 return Arrays.asList(functionImplType, functionType);
125 }
126
127 @NotNull
128 public Collection<JetType> getSupertypesForCallableReference(@NotNull FunctionDescriptor descriptor) {
129 ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
130 ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
131
132 List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(2);
133
134 ClassDescriptor classDescriptor;
135 JetType receiverType;
136 if (receiverParameter != null) {
137 classDescriptor = kExtensionFunctionImpl;
138 receiverType = receiverParameter.getType();
139 typeArguments.add(new TypeProjectionImpl(receiverType));
140 }
141 else if (expectedThisObject != null) {
142 classDescriptor = kMemberFunctionImpl;
143 receiverType = expectedThisObject.getType();
144 typeArguments.add(new TypeProjectionImpl(receiverType));
145 }
146 else {
147 classDescriptor = kFunctionImpl;
148 receiverType = null;
149 }
150
151 //noinspection ConstantConditions
152 typeArguments.add(new TypeProjectionImpl(descriptor.getReturnType()));
153
154 JetType kFunctionImplType = new JetTypeImpl(
155 classDescriptor.getDefaultType().getAnnotations(),
156 classDescriptor.getTypeConstructor(),
157 false,
158 typeArguments,
159 classDescriptor.getMemberScope(typeArguments)
160 );
161
162 JetType kFunctionType = reflectionTypes.getKFunctionType(
163 Annotations.EMPTY,
164 receiverType,
165 DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()),
166 descriptor.getReturnType(),
167 receiverParameter != null
168 );
169
170 return Arrays.asList(kFunctionImplType, kFunctionType);
171 }
172 }