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.descriptors.impl;
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.name.Name;
024 import org.jetbrains.kotlin.resolve.DescriptorFactory;
025 import org.jetbrains.kotlin.types.DescriptorSubstitutor;
026 import org.jetbrains.kotlin.types.JetType;
027 import org.jetbrains.kotlin.types.TypeSubstitutor;
028 import org.jetbrains.kotlin.types.Variance;
029 import org.jetbrains.kotlin.utils.SmartSet;
030 import org.jetbrains.kotlin.utils.UtilsPackage;
031
032 import java.util.ArrayList;
033 import java.util.Collection;
034 import java.util.List;
035 import java.util.Set;
036
037 public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
038 private List<TypeParameterDescriptor> typeParameters;
039 private List<ValueParameterDescriptor> unsubstitutedValueParameters;
040 private JetType unsubstitutedReturnType;
041 private ReceiverParameterDescriptor extensionReceiverParameter;
042 private ReceiverParameterDescriptor dispatchReceiverParameter;
043 private Modality modality;
044 private Visibility visibility = Visibilities.UNKNOWN;
045 private final Set<FunctionDescriptor> overriddenFunctions = SmartSet.create();
046 private final FunctionDescriptor original;
047 private final Kind kind;
048
049 protected FunctionDescriptorImpl(
050 @NotNull DeclarationDescriptor containingDeclaration,
051 @Nullable FunctionDescriptor original,
052 @NotNull Annotations annotations,
053 @NotNull Name name,
054 @NotNull Kind kind,
055 @NotNull SourceElement source
056 ) {
057 super(containingDeclaration, annotations, name, source);
058 this.original = original == null ? this : original;
059 this.kind = kind;
060 }
061
062 @NotNull
063 public FunctionDescriptorImpl initialize(
064 @Nullable JetType receiverParameterType,
065 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
066 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
067 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
068 @Nullable JetType unsubstitutedReturnType,
069 @Nullable Modality modality,
070 @NotNull Visibility visibility
071 ) {
072 this.typeParameters = UtilsPackage.toReadOnlyList(typeParameters);
073 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
074 this.unsubstitutedReturnType = unsubstitutedReturnType;
075 this.modality = modality;
076 this.visibility = visibility;
077 this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
078 this.dispatchReceiverParameter = dispatchReceiverParameter;
079
080 for (int i = 0; i < typeParameters.size(); ++i) {
081 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
082 if (typeParameterDescriptor.getIndex() != i) {
083 throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
084 }
085 }
086
087 for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
088 // TODO fill me
089 int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
090 ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
091 if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
092 throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
093 }
094 }
095
096 return this;
097 }
098
099 public void setVisibility(@NotNull Visibility visibility) {
100 this.visibility = visibility;
101 }
102
103 public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
104 if (this.unsubstitutedReturnType != null) {
105 // TODO: uncomment and fix tests
106 //throw new IllegalStateException("returnType already set");
107 }
108 this.unsubstitutedReturnType = unsubstitutedReturnType;
109 }
110
111 @Nullable
112 @Override
113 public ReceiverParameterDescriptor getExtensionReceiverParameter() {
114 return extensionReceiverParameter;
115 }
116
117 @Nullable
118 @Override
119 public ReceiverParameterDescriptor getDispatchReceiverParameter() {
120 return dispatchReceiverParameter;
121 }
122
123 @NotNull
124 @Override
125 public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
126 return overriddenFunctions;
127 }
128
129 @NotNull
130 @Override
131 public Modality getModality() {
132 return modality;
133 }
134
135 @NotNull
136 @Override
137 public Visibility getVisibility() {
138 return visibility;
139 }
140
141 @Override
142 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
143 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
144 }
145
146 @Override
147 @NotNull
148 public List<TypeParameterDescriptor> getTypeParameters() {
149 return typeParameters;
150 }
151
152 @Override
153 @NotNull
154 public List<ValueParameterDescriptor> getValueParameters() {
155 return unsubstitutedValueParameters;
156 }
157
158 @Override
159 public boolean hasStableParameterNames() {
160 return true;
161 }
162
163 @Override
164 public boolean hasSynthesizedParameterNames() {
165 return false;
166 }
167
168 @Override
169 public JetType getReturnType() {
170 return unsubstitutedReturnType;
171 }
172
173 @NotNull
174 @Override
175 public FunctionDescriptor getOriginal() {
176 return original == this ? this : original.getOriginal();
177 }
178
179 @NotNull
180 @Override
181 public Kind getKind() {
182 return kind;
183 }
184
185 @Override
186 public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
187 if (originalSubstitutor.isEmpty()) {
188 return this;
189 }
190 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, getOriginal(), true, getKind());
191 }
192
193 @Nullable
194 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
195 @NotNull DeclarationDescriptor newOwner,
196 @NotNull Modality newModality,
197 @NotNull Visibility newVisibility,
198 @Nullable FunctionDescriptor original,
199 boolean copyOverrides,
200 @NotNull Kind kind
201 ) {
202 return doSubstitute(originalSubstitutor,
203 newOwner, newModality, newVisibility, original, copyOverrides, kind,
204 getValueParameters(), getExtensionReceiverParameterType(), getReturnType()
205 );
206 }
207
208 @Nullable
209 protected JetType getExtensionReceiverParameterType() {
210 if (extensionReceiverParameter == null) return null;
211 return extensionReceiverParameter.getType();
212 }
213
214
215 @Nullable
216 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
217 @NotNull DeclarationDescriptor newOwner,
218 @NotNull Modality newModality,
219 @NotNull Visibility newVisibility,
220 @Nullable FunctionDescriptor original,
221 boolean copyOverrides,
222 @NotNull Kind kind,
223 @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
224 @Nullable JetType newExtensionReceiverParameterType,
225 @NotNull JetType newReturnType
226 ) {
227 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind);
228
229 List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
230 List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
231 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
232 originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
233 );
234
235 JetType substitutedReceiverParameterType = null;
236 if (newExtensionReceiverParameterType != null) {
237 substitutedReceiverParameterType = substitutor.substitute(newExtensionReceiverParameterType, Variance.IN_VARIANCE);
238 if (substitutedReceiverParameterType == null) {
239 return null;
240 }
241 }
242
243 ReceiverParameterDescriptor substitutedExpectedThis = null;
244 if (dispatchReceiverParameter != null) {
245 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
246 // E.g.
247 // class Base { fun foo() }
248 // class Derived : Base
249 // val x: Base
250 // if (x is Derived) {
251 // // `x` shouldn't be marked as smart-cast
252 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
253 // x.foo()
254 // }
255 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
256 if (substitutedExpectedThis == null) {
257 return null;
258 }
259 }
260
261 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
262 substitutedDescriptor, newValueParameterDescriptors, substitutor
263 );
264 if (substitutedValueParameters == null) {
265 return null;
266 }
267
268 JetType substitutedReturnType = substitutor.substitute(newReturnType, Variance.OUT_VARIANCE);
269 if (substitutedReturnType == null) {
270 return null;
271 }
272
273 substitutedDescriptor.initialize(
274 substitutedReceiverParameterType,
275 substitutedExpectedThis,
276 substitutedTypeParameters,
277 substitutedValueParameters,
278 substitutedReturnType,
279 newModality,
280 newVisibility
281 );
282
283 if (copyOverrides) {
284 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
285 substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
286 }
287 }
288
289 return substitutedDescriptor;
290 }
291
292 @NotNull
293 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
294 @NotNull DeclarationDescriptor newOwner,
295 @Nullable FunctionDescriptor original,
296 @NotNull Kind kind
297 );
298
299 @Override
300 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
301 return visitor.visitFunctionDescriptor(this, data);
302 }
303
304 @Nullable
305 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
306 FunctionDescriptor substitutedDescriptor,
307 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
308 @NotNull TypeSubstitutor substitutor
309 ) {
310 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
311 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
312 // TODO : Lazy?
313 JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
314 JetType varargElementType = unsubstitutedValueParameter.getVarargElementType();
315 JetType substituteVarargElementType =
316 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
317 if (substitutedType == null) return null;
318 result.add(
319 new ValueParameterDescriptorImpl(
320 substitutedDescriptor,
321 unsubstitutedValueParameter,
322 unsubstitutedValueParameter.getIndex(),
323 unsubstitutedValueParameter.getAnnotations(),
324 unsubstitutedValueParameter.getName(),
325 substitutedType,
326 unsubstitutedValueParameter.declaresDefaultValue(),
327 substituteVarargElementType,
328 SourceElement.NO_SOURCE
329 )
330 );
331 }
332 return result;
333 }
334 }