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.SimpleFunctionDescriptorImpl;
023    import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
024    import org.jetbrains.kotlin.name.Name;
025    import org.jetbrains.kotlin.resolve.DescriptorUtils;
026    import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
027    import org.jetbrains.kotlin.types.JetType;
028    
029    import java.util.ArrayList;
030    import java.util.List;
031    
032    import static org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
033    
034    public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl implements AccessorForCallableDescriptor<FunctionDescriptor> {
035    
036        private final FunctionDescriptor calleeDescriptor;
037    
038        public AccessorForFunctionDescriptor(
039                @NotNull FunctionDescriptor descriptor,
040                @NotNull DeclarationDescriptor containingDeclaration,
041                int index
042        ) {
043            super(containingDeclaration, null, Annotations.EMPTY,
044                  Name.identifier("access$" + (descriptor instanceof ConstructorDescriptor ? "init" : descriptor.getName()) + "$" + index),
045                  Kind.DECLARATION, SourceElement.NO_SOURCE);
046            this.calleeDescriptor = descriptor;
047    
048            initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
049                       descriptor instanceof ConstructorDescriptor || AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)
050                            ? NO_RECEIVER_PARAMETER
051                            : descriptor.getDispatchReceiverParameter(),
052                       copyTypeParameters(descriptor),
053                       copyValueParameters(descriptor),
054                       descriptor.getReturnType(),
055                       Modality.FINAL,
056                       Visibilities.INTERNAL);
057        }
058    
059        @NotNull
060        private List<TypeParameterDescriptor> copyTypeParameters(@NotNull FunctionDescriptor descriptor) {
061            List<TypeParameterDescriptor> typeParameters = descriptor.getTypeParameters();
062            List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
063            for (TypeParameterDescriptor typeParameter : typeParameters) {
064                TypeParameterDescriptorImpl copy = TypeParameterDescriptorImpl.createForFurtherModification(
065                        this, typeParameter.getAnnotations(), typeParameter.isReified(),
066                        typeParameter.getVariance(), typeParameter.getName(), typeParameter.getIndex(), SourceElement.NO_SOURCE
067                );
068                for (JetType upperBound : typeParameter.getUpperBounds()) {
069                    copy.addUpperBound(upperBound);
070                }
071                copy.setInitialized();
072                result.add(copy);
073            }
074            return result;
075        }
076    
077        @NotNull
078        private List<ValueParameterDescriptor> copyValueParameters(@NotNull FunctionDescriptor descriptor) {
079            List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters();
080            List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(valueParameters.size());
081            for (ValueParameterDescriptor valueParameter : valueParameters) {
082                result.add(valueParameter.copy(this, valueParameter.getName()));
083            }
084            return result;
085        }
086    
087        @NotNull
088        @Override
089        public FunctionDescriptor getCalleeDescriptor() {
090            return calleeDescriptor;
091        }
092    }