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 doSubstitute(newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()));
288 }
289
290 @Nullable
291 protected KotlinType getExtensionReceiverParameterType() {
292 if (extensionReceiverParameter == null) return null;
293 return extensionReceiverParameter.getType();
294 }
295
296 public class CopyConfiguration {
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 @NotNull
338 protected CopyConfiguration setOwner(@NotNull DeclarationDescriptor owner) {
339 this.newOwner = owner;
340 return this;
341 }
342
343 @NotNull
344 public CopyConfiguration setModality(@NotNull Modality modality) {
345 this.newModality = modality;
346 return this;
347 }
348
349 @NotNull
350 public CopyConfiguration setVisibility(@NotNull Visibility visibility) {
351 this.newVisibility = visibility;
352 return this;
353 }
354
355 @NotNull
356 public CopyConfiguration setKind(@NotNull Kind kind) {
357 this.kind = kind;
358 return this;
359 }
360
361 @NotNull
362 public CopyConfiguration setCopyOverrides(boolean copyOverrides) {
363 this.copyOverrides = copyOverrides;
364 return this;
365 }
366
367 @NotNull
368 public CopyConfiguration setName(@NotNull Name name) {
369 this.name = name;
370 return this;
371 }
372
373 @NotNull
374 public CopyConfiguration setValueParameters(@NotNull List<ValueParameterDescriptor> parameters) {
375 this.newValueParameterDescriptors = parameters;
376 return this;
377 }
378
379 @NotNull
380 public CopyConfiguration setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters) {
381 this.newTypeParameters = parameters;
382 return this;
383 }
384
385 public CopyConfiguration setReturnType(@NotNull KotlinType type) {
386 this.newReturnType = type;
387 return this;
388 }
389
390 public CopyConfiguration setExtensionReceiverType(@Nullable KotlinType type) {
391 this.newExtensionReceiverParameterType = type;
392 return this;
393 }
394
395 @NotNull
396 public CopyConfiguration setOriginal(@NotNull FunctionDescriptor original) {
397 this.original = original;
398 return this;
399 }
400
401 @NotNull
402 public CopyConfiguration setSignatureChange() {
403 this.signatureChange = true;
404 return this;
405 }
406
407 @NotNull
408 public CopyConfiguration setPreserveSourceElement() {
409 this.preserveSourceElement = true;
410 return this;
411 }
412
413 @NotNull
414 public CopyConfiguration setDropOriginalInContainingParts() {
415 this.dropOriginalInContainingParts = true;
416 return this;
417 }
418
419 @NotNull
420 public CopyConfiguration setHidden() {
421 isHiddenToOvercomeSignatureClash = true;
422 return this;
423 }
424
425 @Nullable
426 public FunctionDescriptor build() {
427 return doSubstitute(this);
428 }
429
430 @Nullable
431 public FunctionDescriptor getOriginal() {
432 return original;
433 }
434
435 @NotNull
436 public TypeSubstitutor getOriginalSubstitutor() {
437 return originalSubstitutor;
438 }
439 }
440
441 @NotNull
442 public CopyConfiguration newCopyBuilder() {
443 return newCopyBuilder(TypeSubstitutor.EMPTY);
444 }
445
446 @NotNull
447 private CopyConfiguration newCopyBuilder(@NotNull TypeSubstitutor substitutor) {
448 return new CopyConfiguration(
449 substitutor,
450 getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(),
451 getExtensionReceiverParameterType(), getReturnType(), null);
452 }
453
454 @Nullable
455 protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) {
456 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
457 configuration.newOwner, configuration.original, configuration.kind, configuration.name,
458 configuration.preserveSourceElement);
459
460 List<TypeParameterDescriptor> substitutedTypeParameters;
461 final TypeSubstitutor substitutor;
462
463 if (configuration.newTypeParameters == null) {
464 List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
465 substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
466 substitutor = DescriptorSubstitutor.substituteTypeParameters(
467 originalTypeParameters, configuration.originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
468 );
469 }
470 else {
471 // They should be already substituted
472 substitutedTypeParameters = configuration.newTypeParameters;
473 substitutor = configuration.originalSubstitutor;
474 }
475
476 KotlinType substitutedReceiverParameterType = null;
477 if (configuration.newExtensionReceiverParameterType != null) {
478 substitutedReceiverParameterType = substitutor.substitute(configuration.newExtensionReceiverParameterType, Variance.IN_VARIANCE);
479 if (substitutedReceiverParameterType == null) {
480 return null;
481 }
482 }
483
484 ReceiverParameterDescriptor substitutedExpectedThis = null;
485 if (dispatchReceiverParameter != null) {
486 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
487 // E.g.
488 // class Base { fun foo() }
489 // class Derived : Base
490 // val x: Base
491 // if (x is Derived) {
492 // // `x` shouldn't be marked as smart-cast
493 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
494 // x.foo()
495 // }
496 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
497 if (substitutedExpectedThis == null) {
498 return null;
499 }
500 }
501
502 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
503 substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor, configuration.dropOriginalInContainingParts
504 );
505 if (substitutedValueParameters == null) {
506 return null;
507 }
508
509 KotlinType substitutedReturnType = substitutor.substitute(configuration.newReturnType, Variance.OUT_VARIANCE);
510 if (substitutedReturnType == null) {
511 return null;
512 }
513
514 substitutedDescriptor.initialize(
515 substitutedReceiverParameterType,
516 substitutedExpectedThis,
517 substitutedTypeParameters,
518 substitutedValueParameters,
519 substitutedReturnType,
520 configuration.newModality,
521 configuration.newVisibility
522 );
523 substitutedDescriptor.setOperator(isOperator);
524 substitutedDescriptor.setInfix(isInfix);
525 substitutedDescriptor.setExternal(isExternal);
526 substitutedDescriptor.setInline(isInline);
527 substitutedDescriptor.setTailrec(isTailrec);
528 substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
529 substitutedDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames);
530 substitutedDescriptor.setHidden(configuration.isHiddenToOvercomeSignatureClash);
531
532 if (configuration.signatureChange || getInitialSignatureDescriptor() != null) {
533 FunctionDescriptor initialSignature = (getInitialSignatureDescriptor() != null ? getInitialSignatureDescriptor() : this);
534 FunctionDescriptor initialSignatureSubstituted = initialSignature.substitute(substitutor);
535 substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
536 }
537
538 if (configuration.copyOverrides && !getOriginal().getOverriddenDescriptors().isEmpty()) {
539 if (configuration.originalSubstitutor.isEmpty()) {
540 Function0<Set<FunctionDescriptor>> overriddenFunctionsTask = lazyOverriddenFunctionsTask;
541 if (overriddenFunctionsTask != null) {
542 substitutedDescriptor.lazyOverriddenFunctionsTask = overriddenFunctionsTask;
543 }
544 else {
545 substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors());
546 }
547 }
548 else {
549 substitutedDescriptor.lazyOverriddenFunctionsTask = new Function0<Set<FunctionDescriptor>>() {
550 @Override
551 public Set<FunctionDescriptor> invoke() {
552 SmartSet<FunctionDescriptor> result = SmartSet.create();
553 for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) {
554 result.add(overriddenFunction.substitute(substitutor));
555 }
556 return result;
557 }
558 };
559 }
560 }
561
562 return substitutedDescriptor;
563 }
564
565 @NotNull
566 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
567 @NotNull DeclarationDescriptor newOwner,
568 @Nullable FunctionDescriptor original,
569 @NotNull Kind kind,
570 @Nullable Name newName,
571 boolean preserveSource
572 );
573
574 @NotNull
575 protected SourceElement getSourceToUseForCopy(boolean preserveSource, @Nullable FunctionDescriptor original) {
576 return preserveSource
577 ? (original != null ? original.getSource() : getOriginal().getSource())
578 : SourceElement.NO_SOURCE;
579 }
580
581 @Override
582 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
583 return visitor.visitFunctionDescriptor(this, data);
584 }
585
586 @Nullable
587 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
588 FunctionDescriptor substitutedDescriptor,
589 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
590 @NotNull TypeSubstitutor substitutor,
591 boolean dropOriginal
592 ) {
593 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
594 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
595 // TODO : Lazy?
596 KotlinType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
597 KotlinType varargElementType = unsubstitutedValueParameter.getVarargElementType();
598 KotlinType substituteVarargElementType =
599 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
600 if (substitutedType == null) return null;
601 result.add(
602 new ValueParameterDescriptorImpl(
603 substitutedDescriptor,
604 dropOriginal ? null : unsubstitutedValueParameter,
605 unsubstitutedValueParameter.getIndex(),
606 unsubstitutedValueParameter.getAnnotations(),
607 unsubstitutedValueParameter.getName(),
608 substitutedType,
609 unsubstitutedValueParameter.declaresDefaultValue(),
610 unsubstitutedValueParameter.isCrossinline(),
611 unsubstitutedValueParameter.isNoinline(),
612 substituteVarargElementType,
613 SourceElement.NO_SOURCE
614 )
615 );
616 }
617 return result;
618 }
619
620 @Override
621 @Nullable
622 public FunctionDescriptor getInitialSignatureDescriptor() {
623 return initialSignatureDescriptor;
624 }
625
626 public void setInitialSignatureDescriptor(@Nullable FunctionDescriptor initialSignatureDescriptor) {
627 this.initialSignatureDescriptor = initialSignatureDescriptor;
628 }
629 }