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.annotations.Nullable;
021    import org.jetbrains.kotlin.descriptors.*;
022    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
023    import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl;
024    import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl;
025    import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl;
026    import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
027    import org.jetbrains.kotlin.name.Name;
028    import org.jetbrains.kotlin.resolve.DescriptorUtils;
029    import org.jetbrains.kotlin.types.KotlinType;
030    
031    import java.util.Collections;
032    
033    public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implements AccessorForCallableDescriptor<PropertyDescriptor> {
034        private final PropertyDescriptor calleeDescriptor;
035        private final ClassDescriptor superCallTarget;
036        private final String nameSuffix;
037        private final boolean withSyntheticGetterAccessor;
038        private final boolean withSyntheticSetterAccessor;
039    
040        public AccessorForPropertyDescriptor(
041                @NotNull PropertyDescriptor property,
042                @NotNull DeclarationDescriptor containingDeclaration,
043                @Nullable ClassDescriptor superCallTarget,
044                @NotNull String nameSuffix,
045                boolean getterAccessorRequired,
046                boolean setterAccessorRequired
047        ) {
048            this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()),
049                 /* dispatchReceiverParameter = */
050                 CodegenUtilKt.isJvmStaticInObjectOrClass(property) ? null : property.getDispatchReceiverParameter(),
051                 containingDeclaration, superCallTarget, nameSuffix,
052                 getterAccessorRequired, setterAccessorRequired);
053        }
054    
055        protected AccessorForPropertyDescriptor(
056                @NotNull PropertyDescriptor original,
057                @NotNull KotlinType propertyType,
058                @Nullable KotlinType receiverType,
059                @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
060                @NotNull DeclarationDescriptor containingDeclaration,
061                @Nullable ClassDescriptor superCallTarget,
062                @NotNull String nameSuffix
063        ) {
064            this(original, propertyType, receiverType, dispatchReceiverParameter, containingDeclaration, superCallTarget, nameSuffix, true, true);
065        }
066    
067        private AccessorForPropertyDescriptor(
068                @NotNull PropertyDescriptor original,
069                @NotNull KotlinType propertyType,
070                @Nullable KotlinType receiverType,
071                @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
072                @NotNull DeclarationDescriptor containingDeclaration,
073                @Nullable ClassDescriptor superCallTarget,
074                @NotNull String nameSuffix,
075                boolean getterAccessorRequired,
076                boolean setterAccessorRequired
077        ) {
078            super(containingDeclaration, null, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.LOCAL,
079                  original.isVar(), Name.identifier("access$" + nameSuffix), Kind.DECLARATION, SourceElement.NO_SOURCE,
080                  false, false, false, false, false, false);
081    
082            this.calleeDescriptor = original;
083            this.superCallTarget = superCallTarget;
084            this.nameSuffix = nameSuffix;
085            setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), dispatchReceiverParameter, receiverType);
086    
087            this.withSyntheticGetterAccessor = getterAccessorRequired;
088            this.withSyntheticSetterAccessor = setterAccessorRequired;
089    
090            PropertyGetterDescriptorImpl getterDescriptor =
091                    getterAccessorRequired ? new Getter(this) : (PropertyGetterDescriptorImpl) original.getGetter();
092            PropertySetterDescriptor setterDescriptor =
093                    setterAccessorRequired ? new Setter(this) : original.getSetter();
094            initialize(getterDescriptor, setterDescriptor);
095        }
096    
097        public static class Getter extends PropertyGetterDescriptorImpl implements AccessorForCallableDescriptor<PropertyGetterDescriptor> {
098            public Getter(AccessorForPropertyDescriptor property) {
099                super(property, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.LOCAL,
100                      /* isDefault = */ false, /* isExternal = */ false, /* isInline = */false, Kind.DECLARATION, null, SourceElement.NO_SOURCE);
101                initialize(property.getType());
102            }
103    
104            @NotNull
105            @Override
106            public PropertyGetterDescriptor getCalleeDescriptor() {
107                //noinspection ConstantConditions
108                return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getGetter();
109            }
110    
111            @Override
112            @Nullable
113            public ClassDescriptor getSuperCallTarget() {
114                return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallTarget();
115            }
116    
117        }
118    
119        public static class Setter extends PropertySetterDescriptorImpl implements AccessorForCallableDescriptor<PropertySetterDescriptor>{
120            public Setter(AccessorForPropertyDescriptor property) {
121                super(property, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.LOCAL,
122                      /* isDefault = */ false, /* isExternal = */ false, /* isInline = */ false, Kind.DECLARATION, null, SourceElement.NO_SOURCE);
123                initializeDefault();
124            }
125    
126            @NotNull
127            @Override
128            public PropertySetterDescriptor getCalleeDescriptor() {
129                //noinspection ConstantConditions
130                return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getSetter();
131            }
132    
133            @Override
134            @Nullable
135            public ClassDescriptor getSuperCallTarget() {
136                return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallTarget();
137            }
138        }
139    
140        @NotNull
141        @Override
142        public PropertyDescriptor getCalleeDescriptor() {
143            return calleeDescriptor;
144        }
145    
146        @Override
147        public ClassDescriptor getSuperCallTarget() {
148            return superCallTarget;
149        }
150    
151        @NotNull
152        public String getAccessorSuffix() {
153            return nameSuffix;
154        }
155    
156        public boolean isWithSyntheticGetterAccessor() {
157            return withSyntheticGetterAccessor;
158        }
159    
160        public boolean isWithSyntheticSetterAccessor() {
161            return withSyntheticSetterAccessor;
162        }
163    }