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 kotlin.jvm.functions.Function0;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.kotlin.descriptors.*;
023 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
024 import org.jetbrains.kotlin.name.Name;
025 import org.jetbrains.kotlin.resolve.DescriptorFactory;
026 import org.jetbrains.kotlin.types.DescriptorSubstitutor;
027 import org.jetbrains.kotlin.types.KotlinType;
028 import org.jetbrains.kotlin.types.TypeSubstitutor;
029 import org.jetbrains.kotlin.types.Variance;
030 import org.jetbrains.kotlin.utils.CollectionsKt;
031 import org.jetbrains.kotlin.utils.SmartSet;
032
033 import java.util.*;
034
035 public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
036 private List<TypeParameterDescriptor> typeParameters;
037 private List<ValueParameterDescriptor> unsubstitutedValueParameters;
038 private KotlinType unsubstitutedReturnType;
039 private ReceiverParameterDescriptor extensionReceiverParameter;
040 private ReceiverParameterDescriptor dispatchReceiverParameter;
041 private Modality modality;
042 private Visibility visibility = Visibilities.UNKNOWN;
043 private boolean isOperator = false;
044 private boolean isInfix = false;
045 private boolean isExternal = false;
046 private boolean isInline = false;
047 private boolean isTailrec = false;
048 private boolean isHidden = false;
049 private boolean hasStableParameterNames = true;
050 private boolean hasSynthesizedParameterNames = false;
051 private Collection<? extends FunctionDescriptor> overriddenFunctions = null;
052 private volatile Function0<Set<FunctionDescriptor>> lazyOverriddenFunctionsTask = null;
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 setHidden(boolean hidden) {
133 isHidden = hidden;
134 }
135
136 public void setReturnType(@NotNull KotlinType unsubstitutedReturnType) {
137 if (this.unsubstitutedReturnType != null) {
138 // TODO: uncomment and fix tests
139 //throw new IllegalStateException("returnType already set");
140 }
141 this.unsubstitutedReturnType = unsubstitutedReturnType;
142 }
143
144 public void setHasStableParameterNames(boolean hasStableParameterNames) {
145 this.hasStableParameterNames = hasStableParameterNames;
146 }
147
148 public void setHasSynthesizedParameterNames(boolean hasSynthesizedParameterNames) {
149 this.hasSynthesizedParameterNames = hasSynthesizedParameterNames;
150 }
151
152 @Nullable
153 @Override
154 public ReceiverParameterDescriptor getExtensionReceiverParameter() {
155 return extensionReceiverParameter;
156 }
157
158 @Nullable
159 @Override
160 public ReceiverParameterDescriptor getDispatchReceiverParameter() {
161 return dispatchReceiverParameter;
162 }
163
164 @NotNull
165 @Override
166 public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
167 performOverriddenLazyCalculationIfNeeded();
168 return overriddenFunctions != null ? overriddenFunctions : Collections.<FunctionDescriptor>emptyList();
169 }
170
171 private void performOverriddenLazyCalculationIfNeeded() {
172 Function0<Set<FunctionDescriptor>> overriddenTask = lazyOverriddenFunctionsTask;
173 if (overriddenTask != null) {
174 overriddenFunctions = overriddenTask.invoke();
175 // Here it's important that this assignment is strictly after previous one
176 // `lazyOverriddenFunctionsTask` is volatile, so when someone will see that it's null,
177 // he can read consistent collection from `overriddenFunctions`,
178 // because it's assignment happens-before of "lazyOverriddenFunctionsTask = null"
179 lazyOverriddenFunctionsTask = null;
180 }
181 }
182
183 @NotNull
184 @Override
185 public Modality getModality() {
186 return modality;
187 }
188
189 @NotNull
190 @Override
191 public Visibility getVisibility() {
192 return visibility;
193 }
194
195 @Override
196 public boolean isOperator() {
197 if (isOperator) return true;
198
199 for (FunctionDescriptor descriptor : getOriginal().getOverriddenDescriptors()) {
200 if (descriptor.isOperator()) return true;
201 }
202
203 return false;
204 }
205
206 @Override
207 public boolean isInfix() {
208 if (isInfix) return true;
209
210 for (FunctionDescriptor descriptor : getOriginal().getOverriddenDescriptors()) {
211 if (descriptor.isInfix()) return true;
212 }
213
214 return false;
215 }
216
217 @Override
218 public boolean isExternal() {
219 return isExternal;
220 }
221
222 @Override
223 public boolean isInline() {
224 return isInline;
225 }
226
227 @Override
228 public boolean isTailrec() {
229 return isTailrec;
230 }
231
232 @Override
233 public boolean isHiddenToOvercomeSignatureClash() {
234 return isHidden;
235 }
236
237 @Override
238 public void setOverriddenDescriptors(@NotNull Collection<? extends CallableMemberDescriptor> overriddenDescriptors) {
239 //noinspection unchecked
240 overriddenFunctions = (Collection<? extends FunctionDescriptor>) overriddenDescriptors;
241 }
242
243 @Override
244 @NotNull
245 public List<TypeParameterDescriptor> getTypeParameters() {
246 return typeParameters;
247 }
248
249 @Override
250 @NotNull
251 public List<ValueParameterDescriptor> getValueParameters() {
252 return unsubstitutedValueParameters;
253 }
254
255 @Override
256 public boolean hasStableParameterNames() {
257 return hasStableParameterNames;
258 }
259
260 @Override
261 public boolean hasSynthesizedParameterNames() {
262 return hasSynthesizedParameterNames;
263 }
264
265 @Override
266 public KotlinType getReturnType() {
267 return unsubstitutedReturnType;
268 }
269
270 @NotNull
271 @Override
272 public FunctionDescriptor getOriginal() {
273 return original == this ? this : original.getOriginal();
274 }
275
276 @NotNull
277 @Override
278 public Kind getKind() {
279 return kind;
280 }
281
282 @Override
283 public FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
284 if (originalSubstitutor.isEmpty()) {
285 return this;
286 }
287 return newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()).build();
288 }
289
290 @Nullable
291 protected KotlinType getExtensionReceiverParameterType() {
292 if (extensionReceiverParameter == null) return null;
293 return extensionReceiverParameter.getType();
294 }
295
296 public class CopyConfiguration implements SimpleFunctionDescriptor.CopyBuilder<FunctionDescriptor> {
297 protected @NotNull TypeSubstitutor originalSubstitutor;
298 protected @NotNull DeclarationDescriptor newOwner;
299 protected @NotNull Modality newModality;
300 protected @NotNull Visibility newVisibility;
301 protected @Nullable FunctionDescriptor original = null;
302 protected @NotNull Kind kind;
303 protected @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors;
304 protected @Nullable KotlinType newExtensionReceiverParameterType;
305 protected @NotNull KotlinType newReturnType;
306 protected @Nullable Name name;
307 protected boolean copyOverrides = true;
308 protected boolean signatureChange = false;
309 protected boolean preserveSourceElement = false;
310 protected boolean dropOriginalInContainingParts = false;
311 private boolean isHiddenToOvercomeSignatureClash;
312 private List<TypeParameterDescriptor> newTypeParameters = null;
313
314 public CopyConfiguration(
315 @NotNull TypeSubstitutor originalSubstitutor,
316 @NotNull DeclarationDescriptor newOwner,
317 @NotNull Modality newModality,
318 @NotNull Visibility newVisibility,
319 @NotNull Kind kind,
320 @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
321 @Nullable KotlinType newExtensionReceiverParameterType,
322 @NotNull KotlinType newReturnType,
323 @Nullable Name name
324 ) {
325 this.originalSubstitutor = originalSubstitutor;
326 this.newOwner = newOwner;
327 this.newModality = newModality;
328 this.newVisibility = newVisibility;
329 this.kind = kind;
330 this.newValueParameterDescriptors = newValueParameterDescriptors;
331 this.newExtensionReceiverParameterType = newExtensionReceiverParameterType;
332 this.newReturnType = newReturnType;
333 this.name = name;
334 this.isHiddenToOvercomeSignatureClash = isHiddenToOvercomeSignatureClash();
335 }
336
337 @Override
338 @NotNull
339 public CopyConfiguration setOwner(@NotNull DeclarationDescriptor owner) {
340 this.newOwner = owner;
341 return this;
342 }
343
344 @Override
345 @NotNull
346 public CopyConfiguration setModality(@NotNull Modality modality) {
347 this.newModality = modality;
348 return this;
349 }
350
351 @Override
352 @NotNull
353 public CopyConfiguration setVisibility(@NotNull Visibility visibility) {
354 this.newVisibility = visibility;
355 return this;
356 }
357
358 @Override
359 @NotNull
360 public CopyConfiguration setKind(@NotNull Kind kind) {
361 this.kind = kind;
362 return this;
363 }
364
365 @Override
366 @NotNull
367 public CopyConfiguration setCopyOverrides(boolean copyOverrides) {
368 this.copyOverrides = copyOverrides;
369 return this;
370 }
371
372 @Override
373 @NotNull
374 public CopyConfiguration setName(@NotNull Name name) {
375 this.name = name;
376 return this;
377 }
378
379 @Override
380 @NotNull
381 public CopyConfiguration setValueParameters(@NotNull List<ValueParameterDescriptor> parameters) {
382 this.newValueParameterDescriptors = parameters;
383 return this;
384 }
385
386 @Override
387 @NotNull
388 public CopyConfiguration setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters) {
389 this.newTypeParameters = parameters;
390 return this;
391 }
392
393 @NotNull
394 @Override
395 public CopyConfiguration setReturnType(@NotNull KotlinType type) {
396 this.newReturnType = type;
397 return this;
398 }
399
400 @NotNull
401 @Override
402 public CopyConfiguration setExtensionReceiverType(@Nullable KotlinType type) {
403 this.newExtensionReceiverParameterType = type;
404 return this;
405 }
406
407 @Override
408 @NotNull
409 public CopyConfiguration setOriginal(@NotNull FunctionDescriptor original) {
410 this.original = original;
411 return this;
412 }
413
414 @Override
415 @NotNull
416 public CopyConfiguration setSignatureChange() {
417 this.signatureChange = true;
418 return this;
419 }
420
421 @Override
422 @NotNull
423 public CopyConfiguration setPreserveSourceElement() {
424 this.preserveSourceElement = true;
425 return this;
426 }
427
428 @Override
429 @NotNull
430 public CopyConfiguration setDropOriginalInContainingParts() {
431 this.dropOriginalInContainingParts = true;
432 return this;
433 }
434
435 @Override
436 @NotNull
437 public CopyConfiguration setHiddenToOvercomeSignatureClash() {
438 isHiddenToOvercomeSignatureClash = true;
439 return this;
440 }
441
442 @Override
443 @Nullable
444 public FunctionDescriptor build() {
445 return doSubstitute(this);
446 }
447
448 @Nullable
449 public FunctionDescriptor getOriginal() {
450 return original;
451 }
452
453 @NotNull
454 public TypeSubstitutor getOriginalSubstitutor() {
455 return originalSubstitutor;
456 }
457 }
458
459 @Override
460 @NotNull
461 public CopyBuilder<? extends FunctionDescriptor> newCopyBuilder() {
462 return newCopyBuilder(TypeSubstitutor.EMPTY);
463 }
464
465 @NotNull
466 private CopyConfiguration newCopyBuilder(@NotNull TypeSubstitutor substitutor) {
467 return new CopyConfiguration(
468 substitutor,
469 getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(),
470 getExtensionReceiverParameterType(), getReturnType(), null);
471 }
472
473 @Nullable
474 protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) {
475 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
476 configuration.newOwner, configuration.original, configuration.kind, configuration.name,
477 configuration.preserveSourceElement);
478
479 List<TypeParameterDescriptor> unsubstitutedTypeParameters =
480 configuration.newTypeParameters == null ? getTypeParameters() : configuration.newTypeParameters;
481
482 List<TypeParameterDescriptor> substitutedTypeParameters =
483 new ArrayList<TypeParameterDescriptor>(unsubstitutedTypeParameters.size());
484 final TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
485 unsubstitutedTypeParameters, configuration.originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
486 );
487
488 KotlinType substitutedReceiverParameterType = null;
489 if (configuration.newExtensionReceiverParameterType != null) {
490 substitutedReceiverParameterType = substitutor.substitute(configuration.newExtensionReceiverParameterType, Variance.IN_VARIANCE);
491 if (substitutedReceiverParameterType == null) {
492 return null;
493 }
494 }
495
496 ReceiverParameterDescriptor substitutedExpectedThis = null;
497 if (dispatchReceiverParameter != null) {
498 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
499 // E.g.
500 // class Base { fun foo() }
501 // class Derived : Base
502 // val x: Base
503 // if (x is Derived) {
504 // // `x` shouldn't be marked as smart-cast
505 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
506 // x.foo()
507 // }
508 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
509 if (substitutedExpectedThis == null) {
510 return null;
511 }
512 }
513
514 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
515 substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor, configuration.dropOriginalInContainingParts
516 );
517 if (substitutedValueParameters == null) {
518 return null;
519 }
520
521 KotlinType substitutedReturnType = substitutor.substitute(configuration.newReturnType, Variance.OUT_VARIANCE);
522 if (substitutedReturnType == null) {
523 return null;
524 }
525
526 substitutedDescriptor.initialize(
527 substitutedReceiverParameterType,
528 substitutedExpectedThis,
529 substitutedTypeParameters,
530 substitutedValueParameters,
531 substitutedReturnType,
532 configuration.newModality,
533 configuration.newVisibility
534 );
535 substitutedDescriptor.setOperator(isOperator);
536 substitutedDescriptor.setInfix(isInfix);
537 substitutedDescriptor.setExternal(isExternal);
538 substitutedDescriptor.setInline(isInline);
539 substitutedDescriptor.setTailrec(isTailrec);
540 substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
541 substitutedDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames);
542 substitutedDescriptor.setHidden(configuration.isHiddenToOvercomeSignatureClash);
543
544 if (configuration.signatureChange || getInitialSignatureDescriptor() != null) {
545 FunctionDescriptor initialSignature = (getInitialSignatureDescriptor() != null ? getInitialSignatureDescriptor() : this);
546 FunctionDescriptor initialSignatureSubstituted = initialSignature.substitute(substitutor);
547 substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
548 }
549
550 if (configuration.copyOverrides && !getOriginal().getOverriddenDescriptors().isEmpty()) {
551 if (configuration.originalSubstitutor.isEmpty()) {
552 Function0<Set<FunctionDescriptor>> overriddenFunctionsTask = lazyOverriddenFunctionsTask;
553 if (overriddenFunctionsTask != null) {
554 substitutedDescriptor.lazyOverriddenFunctionsTask = overriddenFunctionsTask;
555 }
556 else {
557 substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors());
558 }
559 }
560 else {
561 substitutedDescriptor.lazyOverriddenFunctionsTask = new Function0<Set<FunctionDescriptor>>() {
562 @Override
563 public Set<FunctionDescriptor> invoke() {
564 SmartSet<FunctionDescriptor> result = SmartSet.create();
565 for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) {
566 result.add(overriddenFunction.substitute(substitutor));
567 }
568 return result;
569 }
570 };
571 }
572 }
573
574 return substitutedDescriptor;
575 }
576
577 @NotNull
578 @Override
579 public FunctionDescriptor copy(
580 DeclarationDescriptor newOwner,
581 Modality modality,
582 Visibility visibility,
583 Kind kind,
584 boolean copyOverrides
585 ) {
586 return newCopyBuilder()
587 .setOwner(newOwner)
588 .setModality(modality)
589 .setVisibility(visibility)
590 .setKind(kind)
591 .setCopyOverrides(copyOverrides)
592 .build();
593 }
594
595 @NotNull
596 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
597 @NotNull DeclarationDescriptor newOwner,
598 @Nullable FunctionDescriptor original,
599 @NotNull Kind kind,
600 @Nullable Name newName,
601 boolean preserveSource
602 );
603
604 @NotNull
605 protected SourceElement getSourceToUseForCopy(boolean preserveSource, @Nullable FunctionDescriptor original) {
606 return preserveSource
607 ? (original != null ? original.getSource() : getOriginal().getSource())
608 : SourceElement.NO_SOURCE;
609 }
610
611 @Override
612 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
613 return visitor.visitFunctionDescriptor(this, data);
614 }
615
616 @Nullable
617 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
618 FunctionDescriptor substitutedDescriptor,
619 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
620 @NotNull TypeSubstitutor substitutor,
621 boolean dropOriginal
622 ) {
623 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
624 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
625 // TODO : Lazy?
626 KotlinType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
627 KotlinType varargElementType = unsubstitutedValueParameter.getVarargElementType();
628 KotlinType substituteVarargElementType =
629 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
630 if (substitutedType == null) return null;
631 result.add(
632 new ValueParameterDescriptorImpl(
633 substitutedDescriptor,
634 dropOriginal ? null : unsubstitutedValueParameter,
635 unsubstitutedValueParameter.getIndex(),
636 unsubstitutedValueParameter.getAnnotations(),
637 unsubstitutedValueParameter.getName(),
638 substitutedType,
639 unsubstitutedValueParameter.declaresDefaultValue(),
640 unsubstitutedValueParameter.isCrossinline(),
641 unsubstitutedValueParameter.isNoinline(),
642 substituteVarargElementType,
643 SourceElement.NO_SOURCE
644 )
645 );
646 }
647 return result;
648 }
649
650 @Override
651 @Nullable
652 public FunctionDescriptor getInitialSignatureDescriptor() {
653 return initialSignatureDescriptor;
654 }
655
656 public void setInitialSignatureDescriptor(@Nullable FunctionDescriptor initialSignatureDescriptor) {
657 this.initialSignatureDescriptor = initialSignatureDescriptor;
658 }
659 }