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.descriptors.annotations.AnnotationsKt;
025    import org.jetbrains.kotlin.name.Name;
026    import org.jetbrains.kotlin.resolve.DescriptorFactory;
027    import org.jetbrains.kotlin.types.*;
028    import org.jetbrains.kotlin.utils.CollectionsKt;
029    import org.jetbrains.kotlin.utils.SmartSet;
030    
031    import java.util.*;
032    
033    public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
034        private List<TypeParameterDescriptor> typeParameters;
035        private List<ValueParameterDescriptor> unsubstitutedValueParameters;
036        private KotlinType unsubstitutedReturnType;
037        private ReceiverParameterDescriptor extensionReceiverParameter;
038        private ReceiverParameterDescriptor dispatchReceiverParameter;
039        private Modality modality;
040        private Visibility visibility = Visibilities.UNKNOWN;
041        private boolean isOperator = false;
042        private boolean isInfix = false;
043        private boolean isExternal = false;
044        private boolean isInline = false;
045        private boolean isTailrec = false;
046        private boolean isHeader = false;
047        private boolean isImpl = false;
048        // Difference between these hidden kinds:
049        // 1. isHiddenToOvercomeSignatureClash prohibit calling such functions even in super-call context
050        // 2. isHiddenForResolutionEverywhereBesideSupercalls propagates to it's overrides descriptors while isHiddenToOvercomeSignatureClash does not
051        private boolean isHiddenToOvercomeSignatureClash = false;
052        private boolean isHiddenForResolutionEverywhereBesideSupercalls = false;
053        private boolean isSuspend = false;
054        private boolean hasStableParameterNames = true;
055        private boolean hasSynthesizedParameterNames = false;
056        private Collection<? extends FunctionDescriptor> overriddenFunctions = null;
057        private volatile Function0<Set<FunctionDescriptor>> lazyOverriddenFunctionsTask = null;
058        private final FunctionDescriptor original;
059        private final Kind kind;
060        @Nullable
061        private FunctionDescriptor initialSignatureDescriptor = null;
062    
063        protected Map<UserDataKey<?>, Object> userDataMap = null;
064    
065        protected FunctionDescriptorImpl(
066                @NotNull DeclarationDescriptor containingDeclaration,
067                @Nullable FunctionDescriptor original,
068                @NotNull Annotations annotations,
069                @NotNull Name name,
070                @NotNull Kind kind,
071                @NotNull SourceElement source
072        ) {
073            super(containingDeclaration, annotations, name, source);
074            this.original = original == null ? this : original;
075            this.kind = kind;
076        }
077    
078        @NotNull
079        public FunctionDescriptorImpl initialize(
080                @Nullable KotlinType receiverParameterType,
081                @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
082                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
083                @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
084                @Nullable KotlinType unsubstitutedReturnType,
085                @Nullable Modality modality,
086                @NotNull Visibility visibility
087        ) {
088            this.typeParameters = CollectionsKt.toReadOnlyList(typeParameters);
089            this.unsubstitutedValueParameters = unsubstitutedValueParameters;
090            this.unsubstitutedReturnType = unsubstitutedReturnType;
091            this.modality = modality;
092            this.visibility = visibility;
093            this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
094            this.dispatchReceiverParameter = dispatchReceiverParameter;
095    
096            for (int i = 0; i < typeParameters.size(); ++i) {
097                TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
098                if (typeParameterDescriptor.getIndex() != i) {
099                    throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
100                }
101            }
102    
103            for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
104                // TODO fill me
105                int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
106                ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
107                if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
108                    throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
109                }
110            }
111    
112            return this;
113        }
114    
115        public void setVisibility(@NotNull Visibility visibility) {
116            this.visibility = visibility;
117        }
118    
119        public void setOperator(boolean isOperator) {
120            this.isOperator = isOperator;
121        }
122    
123        public void setInfix(boolean isInfix) {
124            this.isInfix = isInfix;
125        }
126    
127        public void setExternal(boolean isExternal) {
128            this.isExternal = isExternal;
129        }
130    
131        public void setInline(boolean isInline) {
132            this.isInline = isInline;
133        }
134    
135        public void setTailrec(boolean isTailrec) {
136            this.isTailrec = isTailrec;
137        }
138    
139        public void setHeader(boolean isHeader) {
140            this.isHeader = isHeader;
141        }
142    
143        public void setImpl(boolean isImpl) {
144            this.isImpl = isImpl;
145        }
146    
147        public void setHiddenToOvercomeSignatureClash(boolean hiddenToOvercomeSignatureClash) {
148            isHiddenToOvercomeSignatureClash = hiddenToOvercomeSignatureClash;
149        }
150    
151        private void setHiddenForResolutionEverywhereBesideSupercalls(boolean hiddenForResolutionEverywhereBesideSupercalls) {
152            isHiddenForResolutionEverywhereBesideSupercalls = hiddenForResolutionEverywhereBesideSupercalls;
153        }
154    
155        public void setSuspend(boolean suspend) {
156            isSuspend = suspend;
157        }
158    
159        public void setReturnType(@NotNull KotlinType unsubstitutedReturnType) {
160            if (this.unsubstitutedReturnType != null) {
161                // TODO: uncomment and fix tests
162                //throw new IllegalStateException("returnType already set");
163            }
164            this.unsubstitutedReturnType = unsubstitutedReturnType;
165        }
166    
167        public void setHasStableParameterNames(boolean hasStableParameterNames) {
168            this.hasStableParameterNames = hasStableParameterNames;
169        }
170    
171        public void setHasSynthesizedParameterNames(boolean hasSynthesizedParameterNames) {
172            this.hasSynthesizedParameterNames = hasSynthesizedParameterNames;
173        }
174    
175        @Nullable
176        @Override
177        public ReceiverParameterDescriptor getExtensionReceiverParameter() {
178            return extensionReceiverParameter;
179        }
180    
181        @Nullable
182        @Override
183        public ReceiverParameterDescriptor getDispatchReceiverParameter() {
184            return dispatchReceiverParameter;
185        }
186    
187        @NotNull
188        @Override
189        public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
190            performOverriddenLazyCalculationIfNeeded();
191            return overriddenFunctions != null ? overriddenFunctions : Collections.<FunctionDescriptor>emptyList();
192        }
193    
194        private void performOverriddenLazyCalculationIfNeeded() {
195            Function0<Set<FunctionDescriptor>> overriddenTask = lazyOverriddenFunctionsTask;
196            if (overriddenTask != null) {
197                overriddenFunctions = overriddenTask.invoke();
198                // Here it's important that this assignment is strictly after previous one
199                // `lazyOverriddenFunctionsTask` is volatile, so when someone will see that it's null,
200                // he can read consistent collection from `overriddenFunctions`,
201                // because it's assignment happens-before of "lazyOverriddenFunctionsTask = null"
202                lazyOverriddenFunctionsTask = null;
203            }
204        }
205    
206        @NotNull
207        @Override
208        public Modality getModality() {
209            return modality;
210        }
211    
212        @NotNull
213        @Override
214        public Visibility getVisibility() {
215            return visibility;
216        }
217    
218        @Override
219        public boolean isOperator() {
220            if (isOperator) return true;
221    
222            for (FunctionDescriptor descriptor : getOriginal().getOverriddenDescriptors()) {
223                if (descriptor.isOperator()) return true;
224            }
225    
226            return false;
227        }
228    
229        @Override
230        public boolean isInfix() {
231            if (isInfix) return true;
232    
233            for (FunctionDescriptor descriptor : getOriginal().getOverriddenDescriptors()) {
234                if (descriptor.isInfix()) return true;
235            }
236    
237            return false;
238        }
239    
240        @Override
241        public boolean isExternal() {
242            return isExternal;
243        }
244    
245        @Override
246        public boolean isInline() {
247            return isInline;
248        }
249    
250        @Override
251        public boolean isTailrec() {
252            return isTailrec;
253        }
254    
255        @Override
256        public boolean isSuspend() {
257            return isSuspend;
258        }
259    
260        @Override
261        public boolean isHeader() {
262            return isHeader;
263        }
264    
265        @Override
266        public boolean isImpl() {
267            return isImpl;
268        }
269    
270        @Override
271        public <V> V getUserData(UserDataKey<V> key) {
272            if (userDataMap == null) return null;
273            //noinspection unchecked
274            return (V) userDataMap.get(key);
275        }
276    
277        @Override
278        public boolean isHiddenToOvercomeSignatureClash() {
279            return isHiddenToOvercomeSignatureClash;
280        }
281    
282        @Override
283        public void setOverriddenDescriptors(@NotNull Collection<? extends CallableMemberDescriptor> overriddenDescriptors) {
284            //noinspection unchecked
285            overriddenFunctions = (Collection<? extends FunctionDescriptor>) overriddenDescriptors;
286            for (FunctionDescriptor function : overriddenFunctions) {
287                if (function.isHiddenForResolutionEverywhereBesideSupercalls()) {
288                    isHiddenForResolutionEverywhereBesideSupercalls = true;
289                    break;
290                }
291            }
292        }
293    
294        @Override
295        @NotNull
296        public List<TypeParameterDescriptor> getTypeParameters() {
297            return typeParameters;
298        }
299    
300        @Override
301        @NotNull
302        public List<ValueParameterDescriptor> getValueParameters() {
303            return unsubstitutedValueParameters;
304        }
305    
306        @Override
307        public boolean hasStableParameterNames() {
308            return hasStableParameterNames;
309        }
310    
311        @Override
312        public boolean hasSynthesizedParameterNames() {
313            return hasSynthesizedParameterNames;
314        }
315    
316        @Override
317        public KotlinType getReturnType() {
318            return unsubstitutedReturnType;
319        }
320    
321        @NotNull
322        @Override
323        public FunctionDescriptor getOriginal() {
324            return original == this ? this : original.getOriginal();
325        }
326    
327        @NotNull
328        @Override
329        public Kind getKind() {
330            return kind;
331        }
332    
333        @Override
334        public FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
335            if (originalSubstitutor.isEmpty()) {
336                return this;
337            }
338            return newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()).build();
339        }
340    
341        @Nullable
342        protected KotlinType getExtensionReceiverParameterType() {
343            if (extensionReceiverParameter == null) return null;
344            return extensionReceiverParameter.getType();
345        }
346    
347        @Override
348        public boolean isHiddenForResolutionEverywhereBesideSupercalls() {
349            return isHiddenForResolutionEverywhereBesideSupercalls;
350        }
351    
352        public class CopyConfiguration implements SimpleFunctionDescriptor.CopyBuilder<FunctionDescriptor> {
353            protected @NotNull TypeSubstitution substitution;
354            protected @NotNull DeclarationDescriptor newOwner;
355            protected @NotNull Modality newModality;
356            protected @NotNull Visibility newVisibility;
357            protected @Nullable FunctionDescriptor original = null;
358            protected @NotNull Kind kind;
359            protected @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors;
360            protected @Nullable KotlinType newExtensionReceiverParameterType;
361            protected @Nullable ReceiverParameterDescriptor dispatchReceiverParameter = FunctionDescriptorImpl.this.dispatchReceiverParameter;
362            protected @NotNull KotlinType newReturnType;
363            protected @Nullable Name name;
364            protected boolean copyOverrides = true;
365            protected boolean signatureChange = false;
366            protected boolean preserveSourceElement = false;
367            protected boolean dropOriginalInContainingParts = false;
368            private boolean isHiddenToOvercomeSignatureClash = isHiddenToOvercomeSignatureClash();
369            private List<TypeParameterDescriptor> newTypeParameters = null;
370            private Annotations additionalAnnotations = null;
371            private boolean isHiddenForResolutionEverywhereBesideSupercalls = isHiddenForResolutionEverywhereBesideSupercalls();
372            private SourceElement sourceElement;
373            private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>();
374            private Boolean newHasSynthesizedParameterNames = null;
375    
376            public CopyConfiguration(
377                    @NotNull TypeSubstitution substitution,
378                    @NotNull DeclarationDescriptor newOwner,
379                    @NotNull Modality newModality,
380                    @NotNull Visibility newVisibility,
381                    @NotNull Kind kind,
382                    @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
383                    @Nullable KotlinType newExtensionReceiverParameterType,
384                    @NotNull KotlinType newReturnType,
385                    @Nullable Name name
386            ) {
387                this.substitution = substitution;
388                this.newOwner = newOwner;
389                this.newModality = newModality;
390                this.newVisibility = newVisibility;
391                this.kind = kind;
392                this.newValueParameterDescriptors = newValueParameterDescriptors;
393                this.newExtensionReceiverParameterType = newExtensionReceiverParameterType;
394                this.newReturnType = newReturnType;
395                this.name = name;
396            }
397    
398            @Override
399            @NotNull
400            public CopyConfiguration setOwner(@NotNull DeclarationDescriptor owner) {
401                this.newOwner = owner;
402                return this;
403            }
404    
405            @Override
406            @NotNull
407            public CopyConfiguration setModality(@NotNull Modality modality) {
408                this.newModality = modality;
409                return this;
410            }
411    
412            @Override
413            @NotNull
414            public CopyConfiguration setVisibility(@NotNull Visibility visibility) {
415                this.newVisibility = visibility;
416                return this;
417            }
418    
419            @Override
420            @NotNull
421            public CopyConfiguration setKind(@NotNull Kind kind) {
422                this.kind = kind;
423                return this;
424            }
425    
426            @Override
427            @NotNull
428            public CopyConfiguration setCopyOverrides(boolean copyOverrides) {
429                this.copyOverrides = copyOverrides;
430                return this;
431            }
432    
433            @Override
434            @NotNull
435            public CopyConfiguration setName(@NotNull Name name) {
436                this.name = name;
437                return this;
438            }
439    
440            @Override
441            @NotNull
442            public CopyConfiguration setValueParameters(@NotNull List<ValueParameterDescriptor> parameters) {
443                this.newValueParameterDescriptors = parameters;
444                return this;
445            }
446    
447            @Override
448            @NotNull
449            public CopyConfiguration setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters) {
450                this.newTypeParameters = parameters;
451                return this;
452            }
453    
454            @NotNull
455            @Override
456            public CopyConfiguration setReturnType(@NotNull KotlinType type) {
457                this.newReturnType = type;
458                return this;
459            }
460    
461            @NotNull
462            @Override
463            public CopyConfiguration setExtensionReceiverType(@Nullable KotlinType type) {
464                this.newExtensionReceiverParameterType = type;
465                return this;
466            }
467    
468            @Override
469            @NotNull
470            public CopyConfiguration setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter) {
471                this.dispatchReceiverParameter = dispatchReceiverParameter;
472                return this;
473            }
474    
475            @Override
476            @NotNull
477            public CopyConfiguration setOriginal(@Nullable FunctionDescriptor original) {
478                this.original = original;
479                return this;
480            }
481    
482            @Override
483            @NotNull
484            public CopyConfiguration setSignatureChange() {
485                this.signatureChange = true;
486                return this;
487            }
488    
489            @Override
490            @NotNull
491            public CopyConfiguration setPreserveSourceElement() {
492                this.preserveSourceElement = true;
493                return this;
494            }
495    
496            @NotNull
497            @Override
498            public CopyBuilder<FunctionDescriptor> setSource(@NotNull SourceElement source) {
499                this.sourceElement = source;
500                return this;
501            }
502    
503            @Override
504            @NotNull
505            public CopyConfiguration setDropOriginalInContainingParts() {
506                this.dropOriginalInContainingParts = true;
507                return this;
508            }
509    
510            @Override
511            @NotNull
512            public CopyConfiguration setHiddenToOvercomeSignatureClash() {
513                isHiddenToOvercomeSignatureClash = true;
514                return this;
515            }
516    
517            @Override
518            @NotNull
519            public CopyConfiguration setHiddenForResolutionEverywhereBesideSupercalls() {
520                isHiddenForResolutionEverywhereBesideSupercalls = true;
521                return this;
522            }
523    
524            @NotNull
525            @Override
526            public CopyConfiguration setAdditionalAnnotations(@NotNull Annotations additionalAnnotations) {
527                this.additionalAnnotations = additionalAnnotations;
528                return this;
529            }
530    
531            public CopyConfiguration setHasSynthesizedParameterNames(boolean value) {
532                this.newHasSynthesizedParameterNames = value;
533                return this;
534            }
535    
536            @NotNull
537            @Override
538            public CopyConfiguration setSubstitution(@NotNull TypeSubstitution substitution) {
539                this.substitution = substitution;
540                return this;
541            }
542    
543            @NotNull
544            @Override
545            public <V> CopyBuilder<FunctionDescriptor> putUserData(@NotNull UserDataKey<V> userDataKey, V value) {
546                userDataMap.put(userDataKey, value);
547                return this;
548            }
549    
550            @Override
551            @Nullable
552            public FunctionDescriptor build() {
553                return doSubstitute(this);
554            }
555    
556            @Nullable
557            public FunctionDescriptor getOriginal() {
558                return original;
559            }
560    
561            @NotNull
562            public TypeSubstitution getSubstitution() {
563                return substitution;
564            }
565        }
566    
567        @Override
568        @NotNull
569        public CopyBuilder<? extends FunctionDescriptor> newCopyBuilder() {
570            return newCopyBuilder(TypeSubstitutor.EMPTY);
571        }
572    
573        @NotNull
574        protected CopyConfiguration newCopyBuilder(@NotNull TypeSubstitutor substitutor) {
575            return new CopyConfiguration(
576                    substitutor.getSubstitution(),
577                    getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(),
578                    getExtensionReceiverParameterType(), getReturnType(), null);
579        }
580    
581        @Nullable
582        protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) {
583            Annotations resultAnnotations =
584                    configuration.additionalAnnotations != null
585                    ? AnnotationsKt.composeAnnotations(getAnnotations(), configuration.additionalAnnotations)
586                    : getAnnotations();
587    
588            FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
589                    configuration.newOwner, configuration.original, configuration.kind, configuration.name, resultAnnotations,
590                    getSourceToUseForCopy(configuration.preserveSourceElement, configuration.original, configuration.sourceElement));
591    
592            List<TypeParameterDescriptor> unsubstitutedTypeParameters =
593                    configuration.newTypeParameters == null ? getTypeParameters() : configuration.newTypeParameters;
594    
595            List<TypeParameterDescriptor> substitutedTypeParameters =
596                    new ArrayList<TypeParameterDescriptor>(unsubstitutedTypeParameters.size());
597            final TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
598                    unsubstitutedTypeParameters, configuration.substitution, substitutedDescriptor, substitutedTypeParameters
599            );
600    
601            KotlinType substitutedReceiverParameterType = null;
602            if (configuration.newExtensionReceiverParameterType != null) {
603                substitutedReceiverParameterType = substitutor.substitute(configuration.newExtensionReceiverParameterType, Variance.IN_VARIANCE);
604                if (substitutedReceiverParameterType == null) {
605                    return null;
606                }
607            }
608    
609            ReceiverParameterDescriptor substitutedExpectedThis = null;
610            if (configuration.dispatchReceiverParameter != null) {
611                // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
612                // E.g.
613                // class Base { fun foo() }
614                // class Derived : Base
615                // val x: Base
616                // if (x is Derived) {
617                //    // `x` shouldn't be marked as smart-cast
618                //    // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
619                //    x.foo()
620                // }
621                substitutedExpectedThis = configuration.dispatchReceiverParameter.substitute(substitutor);
622                if (substitutedExpectedThis == null) {
623                    return null;
624                }
625            }
626    
627            List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
628                    substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor, configuration.dropOriginalInContainingParts,
629                    configuration.preserveSourceElement
630            );
631            if (substitutedValueParameters == null) {
632                return null;
633            }
634    
635            KotlinType substitutedReturnType = substitutor.substitute(configuration.newReturnType, Variance.OUT_VARIANCE);
636            if (substitutedReturnType == null) {
637                return null;
638            }
639    
640            substitutedDescriptor.initialize(
641                    substitutedReceiverParameterType,
642                    substitutedExpectedThis,
643                    substitutedTypeParameters,
644                    substitutedValueParameters,
645                    substitutedReturnType,
646                    configuration.newModality,
647                    configuration.newVisibility
648            );
649            substitutedDescriptor.setOperator(isOperator);
650            substitutedDescriptor.setInfix(isInfix);
651            substitutedDescriptor.setExternal(isExternal);
652            substitutedDescriptor.setInline(isInline);
653            substitutedDescriptor.setTailrec(isTailrec);
654            substitutedDescriptor.setSuspend(isSuspend);
655            substitutedDescriptor.setHeader(isHeader);
656            substitutedDescriptor.setImpl(isImpl);
657            substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
658            substitutedDescriptor.setHiddenToOvercomeSignatureClash(configuration.isHiddenToOvercomeSignatureClash);
659            substitutedDescriptor.setHiddenForResolutionEverywhereBesideSupercalls(configuration.isHiddenForResolutionEverywhereBesideSupercalls);
660    
661            substitutedDescriptor.setHasSynthesizedParameterNames(
662                    configuration.newHasSynthesizedParameterNames != null ? configuration.newHasSynthesizedParameterNames : hasSynthesizedParameterNames
663            );
664    
665            if (!configuration.userDataMap.isEmpty() || userDataMap != null) {
666                Map<UserDataKey<?>, Object> newMap = configuration.userDataMap;
667    
668                if (userDataMap != null) {
669                    for (Map.Entry<UserDataKey<?>, Object> entry : userDataMap.entrySet()) {
670                        if (!newMap.containsKey(entry.getKey())) {
671                            newMap.put(entry.getKey(), entry.getValue());
672                        }
673                    }
674                }
675    
676                if (newMap.size() == 1) {
677                    substitutedDescriptor.userDataMap =
678                            Collections.<UserDataKey<?>, Object>singletonMap(
679                                    newMap.keySet().iterator().next(), newMap.values().iterator().next());
680                }
681                else {
682                    substitutedDescriptor.userDataMap = newMap;
683                }
684            }
685    
686            if (configuration.signatureChange || getInitialSignatureDescriptor() != null) {
687                FunctionDescriptor initialSignature = (getInitialSignatureDescriptor() != null ? getInitialSignatureDescriptor() : this);
688                FunctionDescriptor initialSignatureSubstituted = initialSignature.substitute(substitutor);
689                substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
690            }
691    
692            if (configuration.copyOverrides && !getOriginal().getOverriddenDescriptors().isEmpty()) {
693                if (configuration.substitution.isEmpty()) {
694                    Function0<Set<FunctionDescriptor>> overriddenFunctionsTask = lazyOverriddenFunctionsTask;
695                    if (overriddenFunctionsTask != null) {
696                        substitutedDescriptor.lazyOverriddenFunctionsTask = overriddenFunctionsTask;
697                    }
698                    else {
699                        substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors());
700                    }
701                }
702                else {
703                    substitutedDescriptor.lazyOverriddenFunctionsTask = new Function0<Set<FunctionDescriptor>>() {
704                        @Override
705                        public Set<FunctionDescriptor> invoke() {
706                            SmartSet<FunctionDescriptor> result = SmartSet.create();
707                            for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) {
708                                result.add(overriddenFunction.substitute(substitutor));
709                            }
710                            return result;
711                        }
712                    };
713                }
714            }
715    
716            return substitutedDescriptor;
717        }
718    
719        @NotNull
720        @Override
721        public FunctionDescriptor copy(
722                DeclarationDescriptor newOwner,
723                Modality modality,
724                Visibility visibility,
725                Kind kind,
726                boolean copyOverrides
727        ) {
728            return newCopyBuilder()
729                    .setOwner(newOwner)
730                    .setModality(modality)
731                    .setVisibility(visibility)
732                    .setKind(kind)
733                    .setCopyOverrides(copyOverrides)
734                    .build();
735        }
736    
737        @NotNull
738        protected abstract FunctionDescriptorImpl createSubstitutedCopy(
739                @NotNull DeclarationDescriptor newOwner,
740                @Nullable FunctionDescriptor original,
741                @NotNull Kind kind,
742                @Nullable Name newName,
743                @NotNull Annotations annotations,
744                @NotNull SourceElement source
745        );
746    
747        @NotNull
748        private SourceElement getSourceToUseForCopy(
749                boolean preserveSource,
750                @Nullable FunctionDescriptor original,
751                @Nullable SourceElement sourceElement
752        ) {
753            if (sourceElement != null) return sourceElement;
754            return preserveSource
755                   ? (original != null ? original.getSource() : getOriginal().getSource())
756                   : SourceElement.NO_SOURCE;
757        }
758    
759        @Override
760        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
761            return visitor.visitFunctionDescriptor(this, data);
762        }
763    
764        @Nullable
765        public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
766                FunctionDescriptor substitutedDescriptor,
767                @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
768                @NotNull TypeSubstitutor substitutor,
769                boolean dropOriginal,
770                boolean preserveSourceElement
771        ) {
772            List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
773            for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
774                // TODO : Lazy?
775                KotlinType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
776                KotlinType varargElementType = unsubstitutedValueParameter.getVarargElementType();
777                KotlinType substituteVarargElementType =
778                        varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
779                if (substitutedType == null) return null;
780                result.add(
781                        new ValueParameterDescriptorImpl(
782                                substitutedDescriptor,
783                                dropOriginal ? null : unsubstitutedValueParameter,
784                                unsubstitutedValueParameter.getIndex(),
785                                unsubstitutedValueParameter.getAnnotations(),
786                                unsubstitutedValueParameter.getName(),
787                                substitutedType,
788                                unsubstitutedValueParameter.declaresDefaultValue(),
789                                unsubstitutedValueParameter.isCrossinline(),
790                                unsubstitutedValueParameter.isNoinline(),
791                                substituteVarargElementType,
792                                preserveSourceElement ? unsubstitutedValueParameter.getSource() : SourceElement.NO_SOURCE
793                        )
794                );
795            }
796            return result;
797        }
798    
799        @Override
800        @Nullable
801        public FunctionDescriptor getInitialSignatureDescriptor() {
802            return initialSignatureDescriptor;
803        }
804    
805        private void setInitialSignatureDescriptor(@Nullable FunctionDescriptor initialSignatureDescriptor) {
806            this.initialSignatureDescriptor = initialSignatureDescriptor;
807        }
808    }