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.JetType;
026 import org.jetbrains.kotlin.types.TypeSubstitutor;
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 @Override
077 public boolean hasStableParameterNames() {
078 assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
079 return parameterNamesStatus.isStable;
080 }
081
082 @Override
083 public boolean hasSynthesizedParameterNames() {
084 assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
085 return parameterNamesStatus.isSynthesized;
086 }
087
088 public void setParameterNamesStatus(boolean hasStableParameterNames, boolean hasSynthesizedParameterNames) {
089 this.parameterNamesStatus = ParameterNamesStatus.get(hasStableParameterNames, hasSynthesizedParameterNames);
090 }
091
092 @NotNull
093 @Override
094 protected JavaMethodDescriptor createSubstitutedCopy(
095 @NotNull DeclarationDescriptor newOwner,
096 @Nullable FunctionDescriptor original,
097 @NotNull Kind kind
098 ) {
099 JavaMethodDescriptor result = new JavaMethodDescriptor(
100 newOwner,
101 (SimpleFunctionDescriptor) original,
102 getAnnotations(),
103 getName(),
104 kind,
105 original != null ? original.getSource() : SourceElement.NO_SOURCE
106 );
107 result.setParameterNamesStatus(hasStableParameterNames(), hasSynthesizedParameterNames());
108 return result;
109 }
110
111 @Override
112 @NotNull
113 public JavaMethodDescriptor enhance(
114 @Nullable JetType enhancedReceiverType,
115 @NotNull List<JetType> enhancedValueParametersTypes,
116 @NotNull JetType enhancedReturnType
117 ) {
118 List<ValueParameterDescriptor> enhancedValueParameters =
119 DescriptorsPackage.createEnhancedValueParameters(enhancedValueParametersTypes, getValueParameters(), this);
120
121 // We use `doSubstitute` here because it does exactly what we need:
122 // 1. creates full copy of descriptor
123 // 2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc.
124 JavaMethodDescriptor enhancedMethod = (JavaMethodDescriptor) doSubstitute(
125 TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(), false, getOriginal(),
126 /* copyOverrides = */ true, getKind(),
127 enhancedValueParameters, enhancedReceiverType, enhancedReturnType
128 );
129
130 assert enhancedMethod != null : "null after substitution while enhancing " + toString();
131 return enhancedMethod;
132 }
133 }