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.load.java.descriptors;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
022    import org.jetbrains.kotlin.descriptors.*;
023    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
024    import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl;
025    import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl;
026    import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl;
027    import org.jetbrains.kotlin.load.java.typeEnhancement.TypeEnhancementKt;
028    import org.jetbrains.kotlin.name.Name;
029    import org.jetbrains.kotlin.types.KotlinType;
030    
031    import java.util.List;
032    
033    public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements JavaCallableMemberDescriptor {
034        private final boolean isStaticFinal;
035    
036        private JavaPropertyDescriptor(
037                @NotNull DeclarationDescriptor containingDeclaration,
038                @NotNull Annotations annotations,
039                @NotNull Modality modality,
040                @NotNull Visibility visibility,
041                boolean isVar,
042                @NotNull Name name,
043                @NotNull SourceElement source,
044                @Nullable PropertyDescriptor original,
045                @NotNull Kind kind,
046                boolean isStaticFinal
047        ) {
048            super(containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, source,
049                  false, false, false, false, false, false);
050    
051            this.isStaticFinal = isStaticFinal;
052        }
053    
054        @NotNull
055        public static JavaPropertyDescriptor create(
056                @NotNull DeclarationDescriptor containingDeclaration,
057                @NotNull Annotations annotations,
058                @NotNull Modality modality,
059                @NotNull Visibility visibility,
060                boolean isVar,
061                @NotNull Name name,
062                @NotNull SourceElement source,
063                boolean isStaticFinal
064        ) {
065            return new JavaPropertyDescriptor(
066                    containingDeclaration, annotations, modality, visibility, isVar, name, source, null, Kind.DECLARATION, isStaticFinal
067            );
068        }
069    
070        @NotNull
071        @Override
072        protected PropertyDescriptorImpl createSubstitutedCopy(
073                @NotNull DeclarationDescriptor newOwner,
074                @NotNull Modality newModality,
075                @NotNull Visibility newVisibility,
076                @Nullable PropertyDescriptor original,
077                @NotNull Kind kind
078        ) {
079            return new JavaPropertyDescriptor(
080                    newOwner, getAnnotations(), newModality, newVisibility, isVar(), getName(), SourceElement.NO_SOURCE, original,
081                    kind, isStaticFinal
082            );
083        }
084    
085        @Override
086        public boolean hasSynthesizedParameterNames() {
087            return false;
088        }
089    
090        @NotNull
091        @Override
092        public JavaCallableMemberDescriptor enhance(
093                @Nullable KotlinType enhancedReceiverType,
094                @NotNull List<KotlinType> enhancedValueParametersTypes,
095                @NotNull KotlinType enhancedReturnType
096        ) {
097            JavaPropertyDescriptor enhanced = new JavaPropertyDescriptor(
098                    getContainingDeclaration(),
099                    getAnnotations(),
100                    getModality(),
101                    getVisibility(),
102                    isVar(),
103                    getName(),
104                    getSource(),
105                    getOriginal(),
106                    getKind(),
107                    isStaticFinal
108            );
109    
110            PropertyGetterDescriptorImpl newGetter = null;
111            PropertyGetterDescriptorImpl getter = getGetter();
112            if (getter != null) {
113                newGetter = new PropertyGetterDescriptorImpl(
114                        enhanced, getter.getAnnotations(), getter.getModality(), getter.getVisibility(),
115                        getter.isDefault(), getter.isExternal(), getter.isInline(), getKind(), getter, getter.getSource()
116                );
117                newGetter.setInitialSignatureDescriptor(getter.getInitialSignatureDescriptor());
118                newGetter.initialize(enhancedReturnType);
119            }
120    
121            PropertySetterDescriptorImpl newSetter = null;
122            PropertySetterDescriptor setter = getSetter();
123            if (setter != null) {
124                newSetter = new PropertySetterDescriptorImpl(
125                        enhanced, setter.getAnnotations(), setter.getModality(), setter.getVisibility(),
126                        setter.isDefault(), setter.isExternal(), setter.isInline(), getKind(), setter, setter.getSource()
127                );
128                newSetter.setInitialSignatureDescriptor(newSetter.getInitialSignatureDescriptor());
129                newSetter.initialize(setter.getValueParameters().get(0));
130            }
131    
132            enhanced.initialize(newGetter, newSetter);
133            enhanced.setSetterProjectedOut(isSetterProjectedOut());
134            if (compileTimeInitializer != null) {
135                enhanced.setCompileTimeInitializer(compileTimeInitializer);
136            }
137    
138            enhanced.setOverriddenDescriptors(getOverriddenDescriptors());
139    
140            enhanced.setType(
141                    enhancedReturnType,
142                    getTypeParameters(), // TODO
143                    getDispatchReceiverParameter(),
144                    enhancedReceiverType
145            );
146            return enhanced;
147        }
148    
149        @Override
150        public boolean isConst() {
151            KotlinType type = getType();
152            return isStaticFinal && ConstUtil.canBeUsedForConstVal(type) &&
153                   (!TypeEnhancementKt.hasEnhancedNullability(type) || KotlinBuiltIns.isString(type));
154        }
155    }