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.KotlinType;
027 import org.jetbrains.kotlin.types.TypeSubstitutor;
028 import org.jetbrains.kotlin.types.Variance;
029 import org.jetbrains.kotlin.utils.CollectionsKt;
030 import org.jetbrains.kotlin.utils.SmartSet;
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 KotlinType unsubstitutedReturnType;
041 private ReceiverParameterDescriptor extensionReceiverParameter;
042 private ReceiverParameterDescriptor dispatchReceiverParameter;
043 private Modality modality;
044 private Visibility visibility = Visibilities.UNKNOWN;
045 private boolean isOperator = false;
046 private boolean isInfix = false;
047 private boolean isExternal = false;
048 private boolean isInline = false;
049 private boolean isTailrec = false;
050 private boolean hasStableParameterNames = true;
051 private boolean hasSynthesizedParameterNames = false;
052 private final Set<FunctionDescriptor> overriddenFunctions = SmartSet.create();
053 private final FunctionDescriptor original;
054 private final Kind kind;
055 @Nullable
056 private FunctionDescriptor initialSignatureDescriptor = null;
057
058 protected FunctionDescriptorImpl(
059 @NotNull DeclarationDescriptor containingDeclaration,
060 @Nullable FunctionDescriptor original,
061 @NotNull Annotations annotations,
062 @NotNull Name name,
063 @NotNull Kind kind,
064 @NotNull SourceElement source
065 ) {
066 super(containingDeclaration, annotations, name, source);
067 this.original = original == null ? this : original;
068 this.kind = kind;
069 }
070
071 @NotNull
072 public FunctionDescriptorImpl initialize(
073 @Nullable KotlinType receiverParameterType,
074 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
075 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
076 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
077 @Nullable KotlinType unsubstitutedReturnType,
078 @Nullable Modality modality,
079 @NotNull Visibility visibility
080 ) {
081 this.typeParameters = CollectionsKt.toReadOnlyList(typeParameters);
082 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
083 this.unsubstitutedReturnType = unsubstitutedReturnType;
084 this.modality = modality;
085 this.visibility = visibility;
086 this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
087 this.dispatchReceiverParameter = dispatchReceiverParameter;
088
089 for (int i = 0; i < typeParameters.size(); ++i) {
090 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
091 if (typeParameterDescriptor.getIndex() != i) {
092 throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
093 }
094 }
095
096 for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
097 // TODO fill me
098 int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
099 ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
100 if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
101 throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
102 }
103 }
104
105 return this;
106 }
107
108 public void setVisibility(@NotNull Visibility visibility) {
109 this.visibility = visibility;
110 }
111
112 public void setOperator(boolean isOperator) {
113 this.isOperator = isOperator;
114 }
115
116 public void setInfix(boolean isInfix) {
117 this.isInfix = isInfix;
118 }
119
120 public void setExternal(boolean isExternal) {
121 this.isExternal = isExternal;
122 }
123
124 public void setInline(boolean isInline) {
125 this.isInline = isInline;
126 }
127
128 public void setTailrec(boolean isTailrec) {
129 this.isTailrec = isTailrec;
130 }
131
132 public void setReturnType(@NotNull KotlinType unsubstitutedReturnType) {
133 if (this.unsubstitutedReturnType != null) {
134 // TODO: uncomment and fix tests
135 //throw new IllegalStateException("returnType already set");
136 }
137 this.unsubstitutedReturnType = unsubstitutedReturnType;
138 }
139
140 public void setHasStableParameterNames(boolean hasStableParameterNames) {
141 this.hasStableParameterNames = hasStableParameterNames;
142 }
143
144 public void setHasSynthesizedParameterNames(boolean hasSynthesizedParameterNames) {
145 this.hasSynthesizedParameterNames = hasSynthesizedParameterNames;
146 }
147
148 @Nullable
149 @Override
150 public ReceiverParameterDescriptor getExtensionReceiverParameter() {
151 return extensionReceiverParameter;
152 }
153
154 @Nullable
155 @Override
156 public ReceiverParameterDescriptor getDispatchReceiverParameter() {
157 return dispatchReceiverParameter;
158 }
159
160 @NotNull
161 @Override
162 public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
163 return overriddenFunctions;
164 }
165
166 @NotNull
167 @Override
168 public Modality getModality() {
169 return modality;
170 }
171
172 @NotNull
173 @Override
174 public Visibility getVisibility() {
175 return visibility;
176 }
177
178 @Override
179 public boolean isOperator() {
180 if (isOperator) return true;
181
182 for (FunctionDescriptor descriptor : overriddenFunctions) {
183 if (descriptor.isOperator()) return true;
184 }
185
186 return false;
187 }
188
189 @Override
190 public boolean isInfix() {
191 if (isInfix) return true;
192
193 for (FunctionDescriptor descriptor : overriddenFunctions) {
194 if (descriptor.isInfix()) return true;
195 }
196
197 return false;
198 }
199
200 @Override
201 public boolean isExternal() {
202 return isExternal;
203 }
204
205 @Override
206 public boolean isInline() {
207 return isInline;
208 }
209
210 @Override
211 public boolean isTailrec() {
212 return isTailrec;
213 }
214
215 @Override
216 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
217 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
218 }
219
220 @Override
221 @NotNull
222 public List<TypeParameterDescriptor> getTypeParameters() {
223 return typeParameters;
224 }
225
226 @Override
227 @NotNull
228 public List<ValueParameterDescriptor> getValueParameters() {
229 return unsubstitutedValueParameters;
230 }
231
232 @Override
233 public boolean hasStableParameterNames() {
234 return hasStableParameterNames;
235 }
236
237 @Override
238 public boolean hasSynthesizedParameterNames() {
239 return hasSynthesizedParameterNames;
240 }
241
242 @Override
243 public KotlinType getReturnType() {
244 return unsubstitutedReturnType;
245 }
246
247 @NotNull
248 @Override
249 public FunctionDescriptor getOriginal() {
250 return original == this ? this : original.getOriginal();
251 }
252
253 @NotNull
254 @Override
255 public Kind getKind() {
256 return kind;
257 }
258
259 @Override
260 public FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
261 if (originalSubstitutor.isEmpty()) {
262 return this;
263 }
264 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility,
265 isOperator, isInfix, isExternal, isInline, isTailrec,
266 hasStableParameterNames, hasSynthesizedParameterNames,
267 getOriginal(), true, getKind());
268 }
269
270 @Nullable
271 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
272 @NotNull DeclarationDescriptor newOwner,
273 @NotNull Modality newModality,
274 @NotNull Visibility newVisibility,
275 boolean isOperator,
276 boolean isInfix,
277 boolean isExternal,
278 boolean isInline,
279 boolean isTailrec,
280 boolean hasStableParameterNames,
281 boolean hasSynthesizedParameterNames,
282 @Nullable FunctionDescriptor original,
283 boolean copyOverrides,
284 @NotNull Kind kind
285 ) {
286 return doSubstitute(originalSubstitutor,
287 newOwner, newModality, newVisibility, isOperator, isInfix, isExternal, isInline, isTailrec,
288 hasStableParameterNames, hasSynthesizedParameterNames,
289 original, copyOverrides, kind,
290 getValueParameters(), getExtensionReceiverParameterType(), getReturnType(),
291 null, /* preserveSource = */ false, /* signatureChange */ false);
292 }
293
294 @Nullable
295 protected KotlinType getExtensionReceiverParameterType() {
296 if (extensionReceiverParameter == null) return null;
297 return extensionReceiverParameter.getType();
298 }
299
300
301 @Nullable
302 protected FunctionDescriptor doSubstitute(
303 @NotNull TypeSubstitutor originalSubstitutor,
304 @NotNull DeclarationDescriptor newOwner,
305 @NotNull Modality newModality,
306 @NotNull Visibility newVisibility,
307 boolean isOperator,
308 boolean isInfix,
309 boolean isExternal,
310 boolean isInline,
311 boolean isTailrec,
312 boolean hasStableParameterNames,
313 boolean hasSynthesizedParameterNames,
314 @Nullable FunctionDescriptor original,
315 boolean copyOverrides,
316 @NotNull Kind kind,
317 @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
318 @Nullable KotlinType newExtensionReceiverParameterType,
319 @NotNull KotlinType newReturnType,
320 @Nullable Name name,
321 boolean preserveSource,
322 boolean signatureChange
323 ) {
324 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind, name, preserveSource);
325
326 List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
327 List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
328 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
329 originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
330 );
331
332 KotlinType substitutedReceiverParameterType = null;
333 if (newExtensionReceiverParameterType != null) {
334 substitutedReceiverParameterType = substitutor.substitute(newExtensionReceiverParameterType, Variance.IN_VARIANCE);
335 if (substitutedReceiverParameterType == null) {
336 return null;
337 }
338 }
339
340 ReceiverParameterDescriptor substitutedExpectedThis = null;
341 if (dispatchReceiverParameter != null) {
342 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
343 // E.g.
344 // class Base { fun foo() }
345 // class Derived : Base
346 // val x: Base
347 // if (x is Derived) {
348 // // `x` shouldn't be marked as smart-cast
349 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
350 // x.foo()
351 // }
352 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
353 if (substitutedExpectedThis == null) {
354 return null;
355 }
356 }
357
358 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
359 substitutedDescriptor, newValueParameterDescriptors, substitutor
360 );
361 if (substitutedValueParameters == null) {
362 return null;
363 }
364
365 KotlinType substitutedReturnType = substitutor.substitute(newReturnType, Variance.OUT_VARIANCE);
366 if (substitutedReturnType == null) {
367 return null;
368 }
369
370 substitutedDescriptor.initialize(
371 substitutedReceiverParameterType,
372 substitutedExpectedThis,
373 substitutedTypeParameters,
374 substitutedValueParameters,
375 substitutedReturnType,
376 newModality,
377 newVisibility
378 );
379 substitutedDescriptor.setOperator(isOperator);
380 substitutedDescriptor.setInfix(isInfix);
381 substitutedDescriptor.setExternal(isExternal);
382 substitutedDescriptor.setInline(isInline);
383 substitutedDescriptor.setTailrec(isTailrec);
384 substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
385 substitutedDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames);
386
387 if (signatureChange || getInitialSignatureDescriptor() != null) {
388 FunctionDescriptor initialSignature = (getInitialSignatureDescriptor() != null ? getInitialSignatureDescriptor() : this);
389 FunctionDescriptor initialSignatureSubstituted = initialSignature.substitute(substitutor);
390 substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
391 }
392
393 if (copyOverrides) {
394 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
395 substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
396 }
397 }
398
399 return substitutedDescriptor;
400 }
401
402 @NotNull
403 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
404 @NotNull DeclarationDescriptor newOwner,
405 @Nullable FunctionDescriptor original,
406 @NotNull Kind kind,
407 @Nullable Name newName,
408 boolean preserveSource
409 );
410
411 @NotNull
412 protected SourceElement getSourceToUseForCopy(boolean preserveSource, @Nullable FunctionDescriptor original) {
413 return preserveSource
414 ? (original != null ? original.getSource() : getOriginal().getSource())
415 : SourceElement.NO_SOURCE;
416 }
417
418 @Override
419 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
420 return visitor.visitFunctionDescriptor(this, data);
421 }
422
423 @Nullable
424 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
425 FunctionDescriptor substitutedDescriptor,
426 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
427 @NotNull TypeSubstitutor substitutor
428 ) {
429 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
430 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
431 // TODO : Lazy?
432 KotlinType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
433 KotlinType varargElementType = unsubstitutedValueParameter.getVarargElementType();
434 KotlinType substituteVarargElementType =
435 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
436 if (substitutedType == null) return null;
437 result.add(
438 new ValueParameterDescriptorImpl(
439 substitutedDescriptor,
440 unsubstitutedValueParameter,
441 unsubstitutedValueParameter.getIndex(),
442 unsubstitutedValueParameter.getAnnotations(),
443 unsubstitutedValueParameter.getName(),
444 substitutedType,
445 unsubstitutedValueParameter.declaresDefaultValue(),
446 unsubstitutedValueParameter.isCrossinline(),
447 unsubstitutedValueParameter.isNoinline(),
448 substituteVarargElementType,
449 SourceElement.NO_SOURCE
450 )
451 );
452 }
453 return result;
454 }
455
456 @Override
457 @Nullable
458 public FunctionDescriptor getInitialSignatureDescriptor() {
459 return initialSignatureDescriptor;
460 }
461
462 public void setInitialSignatureDescriptor(@Nullable FunctionDescriptor initialSignatureDescriptor) {
463 this.initialSignatureDescriptor = initialSignatureDescriptor;
464 }
465 }