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$.canBeOperator(descriptor));
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 boolean preserveSource
118 ) {
119 JavaMethodDescriptor result = new JavaMethodDescriptor(
120 newOwner,
121 (SimpleFunctionDescriptor) original,
122 getAnnotations(),
123 newName != null ? newName : getName(),
124 kind,
125 getSourceToUseForCopy(preserveSource, original)
126 );
127 result.setParameterNamesStatus(hasStableParameterNames(), hasSynthesizedParameterNames());
128 return result;
129 }
130
131 @Override
132 @NotNull
133 public JavaMethodDescriptor enhance(
134 @Nullable KotlinType enhancedReceiverType,
135 @NotNull List<KotlinType> enhancedValueParametersTypes,
136 @NotNull KotlinType enhancedReturnType
137 ) {
138 List<ValueParameterDescriptor> enhancedValueParameters =
139 UtilKt.copyValueParameters(enhancedValueParametersTypes, getValueParameters(), this);
140
141 // We use `doSubstitute` here because it does exactly what we need:
142 // 1. creates full copy of descriptor
143 // 2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc.
144 JavaMethodDescriptor enhancedMethod =
145 (JavaMethodDescriptor) newCopyBuilder()
146 .setValueParameters(enhancedValueParameters)
147 .setReturnType(enhancedReturnType)
148 .setExtensionReceiverType(enhancedReceiverType)
149 .setOriginal(getOriginal())
150 .build();
151
152 assert enhancedMethod != null : "null after substitution while enhancing " + toString();
153 return enhancedMethod;
154 }
155 }