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.types.TypeSubstitutor;
027 import org.jetbrains.kotlin.util.OperatorChecks;
028
029 import java.util.List;
030
031 public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implements JavaCallableMemberDescriptor {
032 private enum ParameterNamesStatus {
033 NON_STABLE_DECLARED(false, false),
034 STABLE_DECLARED(true, false),
035 NON_STABLE_SYNTHESIZED(false, true),
036 STABLE_SYNTHESIZED(true, true), // TODO: this makes no sense
037 ;
038
039 public final boolean isStable;
040 public final boolean isSynthesized;
041
042 ParameterNamesStatus(boolean isStable, boolean isSynthesized) {
043 this.isStable = isStable;
044 this.isSynthesized = isSynthesized;
045 }
046
047 @NotNull
048 public static ParameterNamesStatus get(boolean stable, boolean synthesized) {
049 return stable ? (synthesized ? STABLE_SYNTHESIZED : STABLE_DECLARED) :
050 (synthesized ? NON_STABLE_SYNTHESIZED : NON_STABLE_DECLARED);
051 }
052 }
053
054 private ParameterNamesStatus parameterNamesStatus = null;
055
056 protected JavaMethodDescriptor(
057 @NotNull DeclarationDescriptor containingDeclaration,
058 @Nullable SimpleFunctionDescriptor original,
059 @NotNull Annotations annotations,
060 @NotNull Name name,
061 @NotNull Kind kind,
062 @NotNull SourceElement source
063 ) {
064 super(containingDeclaration, original, annotations, name, kind, source);
065 }
066
067 @NotNull
068 public static JavaMethodDescriptor createJavaMethod(
069 @NotNull DeclarationDescriptor containingDeclaration,
070 @NotNull Annotations annotations,
071 @NotNull Name name,
072 @NotNull SourceElement source
073 ) {
074 return new JavaMethodDescriptor(containingDeclaration, null, annotations, name, Kind.DECLARATION, source);
075 }
076
077 @NotNull
078 @Override
079 public SimpleFunctionDescriptorImpl initialize(
080 @Nullable KotlinType receiverParameterType,
081 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
082 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
083 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
084 @Nullable KotlinType unsubstitutedReturnType,
085 @Nullable Modality modality,
086 @NotNull Visibility visibility
087 ) {
088 SimpleFunctionDescriptorImpl descriptor = super.initialize(
089 receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters,
090 unsubstitutedReturnType, modality, visibility);
091 setOperator(OperatorChecks.INSTANCE$.canBeOperator(descriptor));
092 return descriptor;
093 }
094
095 @Override
096 public boolean hasStableParameterNames() {
097 assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
098 return parameterNamesStatus.isStable;
099 }
100
101 @Override
102 public boolean hasSynthesizedParameterNames() {
103 assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
104 return parameterNamesStatus.isSynthesized;
105 }
106
107 public void setParameterNamesStatus(boolean hasStableParameterNames, boolean hasSynthesizedParameterNames) {
108 this.parameterNamesStatus = ParameterNamesStatus.get(hasStableParameterNames, hasSynthesizedParameterNames);
109 }
110
111 @NotNull
112 @Override
113 protected JavaMethodDescriptor createSubstitutedCopy(
114 @NotNull DeclarationDescriptor newOwner,
115 @Nullable FunctionDescriptor original,
116 @NotNull Kind kind,
117 @Nullable Name newName,
118 boolean preserveSource
119 ) {
120 JavaMethodDescriptor result = new JavaMethodDescriptor(
121 newOwner,
122 (SimpleFunctionDescriptor) original,
123 getAnnotations(),
124 newName != null ? newName : getName(),
125 kind,
126 getSourceToUseForCopy(preserveSource, original)
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 // We use `doSubstitute` here because it does exactly what we need:
143 // 1. creates full copy of descriptor
144 // 2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc.
145 JavaMethodDescriptor enhancedMethod = (JavaMethodDescriptor) doSubstitute(
146 TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(),
147 isOperator(), isInfix(), isExternal(), isInline(), isTailrec(), hasStableParameterNames(), hasSynthesizedParameterNames(),
148 getOriginal(), /* copyOverrides = */ true, getKind(),
149 enhancedValueParameters, enhancedReceiverType, enhancedReturnType,
150 null, /* preserveSource */false, /* signatureChange = */ false);
151
152 assert enhancedMethod != null : "null after substitution while enhancing " + toString();
153 return enhancedMethod;
154 }
155 }