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.descriptors.*;
022    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
023    import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
024    import org.jetbrains.kotlin.name.Name;
025    import org.jetbrains.kotlin.types.KotlinType;
026    import org.jetbrains.kotlin.util.OperatorChecks;
027    
028    import java.util.List;
029    
030    public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implements JavaCallableMemberDescriptor {
031        private enum ParameterNamesStatus {
032            NON_STABLE_DECLARED(false, false),
033            STABLE_DECLARED(true, false),
034            NON_STABLE_SYNTHESIZED(false, true),
035            STABLE_SYNTHESIZED(true, true), // TODO: this makes no sense
036            ;
037    
038            public final boolean isStable;
039            public final boolean isSynthesized;
040    
041            ParameterNamesStatus(boolean isStable, boolean isSynthesized) {
042                this.isStable = isStable;
043                this.isSynthesized = isSynthesized;
044            }
045    
046            @NotNull
047            public static ParameterNamesStatus get(boolean stable, boolean synthesized) {
048                return stable ? (synthesized ? STABLE_SYNTHESIZED : STABLE_DECLARED) :
049                       (synthesized ? NON_STABLE_SYNTHESIZED : NON_STABLE_DECLARED);
050            }
051        }
052    
053        private ParameterNamesStatus parameterNamesStatus = null;
054    
055        protected JavaMethodDescriptor(
056                @NotNull DeclarationDescriptor containingDeclaration,
057                @Nullable SimpleFunctionDescriptor original,
058                @NotNull Annotations annotations,
059                @NotNull Name name,
060                @NotNull Kind kind,
061                @NotNull SourceElement source
062        ) {
063            super(containingDeclaration, original, annotations, name, kind, source);
064        }
065    
066        @NotNull
067        public static JavaMethodDescriptor createJavaMethod(
068                @NotNull DeclarationDescriptor containingDeclaration,
069                @NotNull Annotations annotations,
070                @NotNull Name name,
071                @NotNull SourceElement source
072        ) {
073            return new JavaMethodDescriptor(containingDeclaration, null, annotations, name, Kind.DECLARATION, source);
074        }
075    
076        @NotNull
077        @Override
078        public SimpleFunctionDescriptorImpl initialize(
079                @Nullable KotlinType receiverParameterType,
080                @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
081                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
082                @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
083                @Nullable KotlinType unsubstitutedReturnType,
084                @Nullable Modality modality,
085                @NotNull Visibility visibility
086        ) {
087            SimpleFunctionDescriptorImpl descriptor = super.initialize(
088                    receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters,
089                    unsubstitutedReturnType, modality, visibility);
090            setOperator(OperatorChecks.INSTANCE.check(descriptor).isSuccess());
091            return descriptor;
092        }
093    
094        @Override
095        public boolean hasStableParameterNames() {
096            assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
097            return parameterNamesStatus.isStable;
098        }
099    
100        @Override
101        public boolean hasSynthesizedParameterNames() {
102            assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
103            return parameterNamesStatus.isSynthesized;
104        }
105    
106        public void setParameterNamesStatus(boolean hasStableParameterNames, boolean hasSynthesizedParameterNames) {
107            this.parameterNamesStatus = ParameterNamesStatus.get(hasStableParameterNames, hasSynthesizedParameterNames);
108        }
109    
110        @NotNull
111        @Override
112        protected JavaMethodDescriptor createSubstitutedCopy(
113                @NotNull DeclarationDescriptor newOwner,
114                @Nullable FunctionDescriptor original,
115                @NotNull Kind kind,
116                @Nullable Name newName,
117                @NotNull Annotations annotations,
118                @NotNull SourceElement source
119        ) {
120            JavaMethodDescriptor result = new JavaMethodDescriptor(
121                    newOwner,
122                    (SimpleFunctionDescriptor) original,
123                    annotations,
124                    newName != null ? newName : getName(),
125                    kind,
126                    source
127            );
128            result.setParameterNamesStatus(hasStableParameterNames(), hasSynthesizedParameterNames());
129            return result;
130        }
131    
132        @Override
133        @NotNull
134        public JavaMethodDescriptor enhance(
135                @Nullable KotlinType enhancedReceiverType,
136                @NotNull List<KotlinType> enhancedValueParametersTypes,
137                @NotNull KotlinType enhancedReturnType
138        ) {
139            List<ValueParameterDescriptor> enhancedValueParameters =
140                    UtilKt.copyValueParameters(enhancedValueParametersTypes, getValueParameters(), this);
141    
142            JavaMethodDescriptor enhancedMethod =
143                    (JavaMethodDescriptor) newCopyBuilder()
144                            .setValueParameters(enhancedValueParameters)
145                            .setReturnType(enhancedReturnType)
146                            .setExtensionReceiverType(enhancedReceiverType)
147                            .setDropOriginalInContainingParts()
148                            .setPreserveSourceElement()
149                            .build();
150    
151            assert enhancedMethod != null : "null after substitution while enhancing " + toString();
152            return enhancedMethod;
153        }
154    }