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.codegen;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.kotlin.descriptors.*;
021    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
022    import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
023    import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor;
024    import org.jetbrains.kotlin.name.FqName;
025    import org.jetbrains.kotlin.name.Name;
026    import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM;
027    import org.jetbrains.kotlin.storage.LockBasedStorageManager;
028    import org.jetbrains.kotlin.types.JetType;
029    import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
030    
031    import java.util.*;
032    
033    import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
034    
035    public class JvmRuntimeTypes {
036        private final ClassDescriptor lambda;
037        private final ClassDescriptor functionReference;
038        private final List<ClassDescriptor> propertyReferences;
039        private final List<ClassDescriptor> mutablePropertyReferences;
040    
041        public JvmRuntimeTypes() {
042            ModuleDescriptorImpl module = new ModuleDescriptorImpl(
043                    Name.special("<jvm functions impl>"),
044                    LockBasedStorageManager.NO_LOCKS,
045                    TopDownAnalyzerFacadeForJVM.JVM_MODULE_PARAMETERS
046            );
047            PackageFragmentDescriptor kotlinJvmInternal = new MutablePackageFragmentDescriptor(module, new FqName("kotlin.jvm.internal"));
048    
049            this.lambda = createClass(kotlinJvmInternal, "Lambda");
050            this.functionReference = createClass(kotlinJvmInternal, "FunctionReference");
051            this.propertyReferences = new ArrayList<ClassDescriptor>(3);
052            this.mutablePropertyReferences = new ArrayList<ClassDescriptor>(3);
053    
054            for (int i = 0; i <= 2; i++) {
055                propertyReferences.add(createClass(kotlinJvmInternal, "PropertyReference" + i));
056                mutablePropertyReferences.add(createClass(kotlinJvmInternal, "MutablePropertyReference" + i));
057            }
058        }
059    
060        @NotNull
061        private static ClassDescriptor createClass(@NotNull PackageFragmentDescriptor packageFragment, @NotNull String name) {
062            MutableClassDescriptor descriptor = new MutableClassDescriptor(
063                    packageFragment, ClassKind.CLASS, false, Name.identifier(name), SourceElement.NO_SOURCE
064            );
065    
066            descriptor.setModality(Modality.FINAL);
067            descriptor.setVisibility(Visibilities.PUBLIC);
068            descriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
069            descriptor.createTypeConstructor();
070    
071            return descriptor;
072        }
073    
074        @NotNull
075        public Collection<JetType> getSupertypesForClosure(@NotNull FunctionDescriptor descriptor) {
076            ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
077    
078            //noinspection ConstantConditions
079            JetType functionType = getBuiltIns(descriptor).getFunctionType(
080                    Annotations.EMPTY,
081                    receiverParameter == null ? null : receiverParameter.getType(),
082                    ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
083                    descriptor.getReturnType()
084            );
085    
086            return Arrays.asList(lambda.getDefaultType(), functionType);
087        }
088    
089        @NotNull
090        public Collection<JetType> getSupertypesForFunctionReference(@NotNull FunctionDescriptor descriptor) {
091            ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
092            ReceiverParameterDescriptor dispatchReceiver = descriptor.getDispatchReceiverParameter();
093    
094            JetType receiverType =
095                    extensionReceiver != null ? extensionReceiver.getType() : dispatchReceiver != null ? dispatchReceiver.getType() : null;
096    
097            //noinspection ConstantConditions
098            JetType functionType = getBuiltIns(descriptor).getFunctionType(
099                    Annotations.EMPTY,
100                    receiverType,
101                    ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
102                    descriptor.getReturnType()
103            );
104    
105            return Arrays.asList(functionReference.getDefaultType(), functionType);
106        }
107    
108        @NotNull
109        public JetType getSupertypeForPropertyReference(@NotNull PropertyDescriptor descriptor) {
110            int arity = (descriptor.getExtensionReceiverParameter() != null ? 1 : 0) +
111                        (descriptor.getDispatchReceiverParameter() != null ? 1 : 0);
112            return (descriptor.isVar() ? mutablePropertyReferences : propertyReferences).get(arity).getDefaultType();
113        }
114    }