001    /*
002     * Copyright 2010-2016 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.resolve;
018    
019    import com.google.common.collect.Lists;
020    import com.google.common.collect.Maps;
021    import com.google.common.collect.Sets;
022    import com.intellij.psi.PsiElement;
023    import kotlin.Pair;
024    import kotlin.collections.CollectionsKt;
025    import kotlin.collections.SetsKt;
026    import kotlin.jvm.functions.Function0;
027    import kotlin.jvm.functions.Function1;
028    import org.jetbrains.annotations.NotNull;
029    import org.jetbrains.annotations.Nullable;
030    import org.jetbrains.kotlin.builtins.FunctionTypesKt;
031    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
032    import org.jetbrains.kotlin.descriptors.*;
033    import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter;
034    import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
035    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
036    import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations;
037    import org.jetbrains.kotlin.descriptors.impl.*;
038    import org.jetbrains.kotlin.diagnostics.Errors;
039    import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
040    import org.jetbrains.kotlin.lexer.KtTokens;
041    import org.jetbrains.kotlin.name.FqName;
042    import org.jetbrains.kotlin.name.Name;
043    import org.jetbrains.kotlin.psi.*;
044    import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
045    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
046    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
047    import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
048    import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
049    import org.jetbrains.kotlin.resolve.scopes.*;
050    import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
051    import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
052    import org.jetbrains.kotlin.storage.StorageManager;
053    import org.jetbrains.kotlin.types.*;
054    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
055    import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
056    import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor;
057    
058    import java.util.*;
059    
060    import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
061    import static org.jetbrains.kotlin.diagnostics.Errors.*;
062    import static org.jetbrains.kotlin.lexer.KtTokens.*;
063    import static org.jetbrains.kotlin.resolve.BindingContext.CONSTRUCTOR;
064    import static org.jetbrains.kotlin.resolve.BindingContext.PACKAGE_TO_FILES;
065    import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
066    import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveModalityFromModifiers;
067    import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers;
068    
069    public class DescriptorResolver {
070        public static final Name COPY_METHOD_NAME = Name.identifier("copy");
071    
072        @NotNull private final TypeResolver typeResolver;
073        @NotNull private final AnnotationResolver annotationResolver;
074        @NotNull private final StorageManager storageManager;
075        @NotNull private final KotlinBuiltIns builtIns;
076        @NotNull private final SupertypeLoopChecker supertypeLoopsResolver;
077        @NotNull private final VariableTypeResolver variableTypeResolver;
078        @NotNull private final ExpressionTypingServices expressionTypingServices;
079    
080        public DescriptorResolver(
081                @NotNull AnnotationResolver annotationResolver,
082                @NotNull KotlinBuiltIns builtIns,
083                @NotNull StorageManager storageManager,
084                @NotNull TypeResolver typeResolver,
085                @NotNull SupertypeLoopChecker supertypeLoopsResolver,
086                @NotNull VariableTypeResolver variableTypeResolver,
087                @NotNull ExpressionTypingServices expressionTypingServices
088        ) {
089            this.annotationResolver = annotationResolver;
090            this.builtIns = builtIns;
091            this.storageManager = storageManager;
092            this.typeResolver = typeResolver;
093            this.supertypeLoopsResolver = supertypeLoopsResolver;
094            this.variableTypeResolver = variableTypeResolver;
095            this.expressionTypingServices = expressionTypingServices;
096        }
097    
098        public List<KotlinType> resolveSupertypes(
099                @NotNull LexicalScope scope,
100                @NotNull ClassDescriptor classDescriptor,
101                @NotNull KtClassOrObject jetClass,
102                BindingTrace trace
103        ) {
104            List<KotlinType> supertypes = Lists.newArrayList();
105            List<KtSuperTypeListEntry> delegationSpecifiers = jetClass.getSuperTypeListEntries();
106            Collection<KotlinType> declaredSupertypes = resolveSuperTypeListEntries(
107                    scope,
108                    delegationSpecifiers,
109                    typeResolver, trace, false);
110    
111            for (KotlinType declaredSupertype : declaredSupertypes) {
112                addValidSupertype(supertypes, declaredSupertype);
113            }
114    
115            if (classDescriptor.getKind() == ClassKind.ENUM_CLASS && !containsClass(supertypes)) {
116                supertypes.add(0, builtIns.getEnumType(classDescriptor.getDefaultType()));
117            }
118    
119            if (supertypes.isEmpty()) {
120                KotlinType defaultSupertype = getDefaultSupertype(jetClass, trace, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
121                addValidSupertype(supertypes, defaultSupertype);
122            }
123    
124            return supertypes;
125        }
126    
127        private static void addValidSupertype(List<KotlinType> supertypes, KotlinType declaredSupertype) {
128            if (!declaredSupertype.isError()) {
129                supertypes.add(declaredSupertype);
130            }
131        }
132    
133        private boolean containsClass(Collection<KotlinType> result) {
134            for (KotlinType type : result) {
135                ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
136                if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.INTERFACE) {
137                    return true;
138                }
139            }
140            return false;
141        }
142    
143        private KotlinType getDefaultSupertype(KtClassOrObject jetClass, BindingTrace trace, boolean isAnnotation) {
144            // TODO : beautify
145            if (jetClass instanceof KtEnumEntry) {
146                KtClassOrObject parent = KtStubbedPsiUtil.getContainingDeclaration(jetClass, KtClassOrObject.class);
147                ClassDescriptor parentDescriptor = trace.getBindingContext().get(BindingContext.CLASS, parent);
148                if (parentDescriptor.getTypeConstructor().getParameters().isEmpty()) {
149                    return parentDescriptor.getDefaultType();
150                }
151                else {
152                    trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(jetClass.getNameIdentifier()));
153                    return ErrorUtils.createErrorType("Supertype not specified");
154                }
155            }
156            else if (isAnnotation) {
157                return builtIns.getAnnotationType();
158            }
159            return builtIns.getAnyType();
160        }
161    
162        public Collection<KotlinType> resolveSuperTypeListEntries(
163                LexicalScope extensibleScope,
164                List<KtSuperTypeListEntry> delegationSpecifiers,
165                @NotNull TypeResolver resolver,
166                BindingTrace trace,
167                boolean checkBounds
168        ) {
169            if (delegationSpecifiers.isEmpty()) {
170                return Collections.emptyList();
171            }
172            Collection<KotlinType> result = Lists.newArrayList();
173            for (KtSuperTypeListEntry delegationSpecifier : delegationSpecifiers) {
174                KtTypeReference typeReference = delegationSpecifier.getTypeReference();
175                if (typeReference != null) {
176                    KotlinType supertype = resolver.resolveType(extensibleScope, typeReference, trace, checkBounds);
177                    if (DynamicTypesKt.isDynamic(supertype)) {
178                        trace.report(DYNAMIC_SUPERTYPE.on(typeReference));
179                    }
180                    else {
181                        result.add(supertype);
182                        KtTypeElement bareSuperType = checkNullableSupertypeAndStripQuestionMarks(trace, typeReference.getTypeElement());
183                        checkProjectionsInImmediateArguments(trace, bareSuperType);
184                    }
185                }
186                else {
187                    result.add(ErrorUtils.createErrorType("No type reference"));
188                }
189            }
190            return result;
191        }
192    
193        @Nullable
194        private static KtTypeElement checkNullableSupertypeAndStripQuestionMarks(@NotNull BindingTrace trace, @Nullable KtTypeElement typeElement) {
195            while (typeElement instanceof KtNullableType) {
196                KtNullableType nullableType = (KtNullableType) typeElement;
197                typeElement = nullableType.getInnerType();
198                // report only for innermost '?', the rest gets a 'redundant' warning
199                if (!(typeElement instanceof KtNullableType) && typeElement != null) {
200                    trace.report(NULLABLE_SUPERTYPE.on(nullableType));
201                }
202            }
203            return typeElement;
204        }
205    
206        private static void checkProjectionsInImmediateArguments(@NotNull BindingTrace trace, @Nullable KtTypeElement typeElement) {
207            if (typeElement instanceof KtUserType) {
208                KtUserType userType = (KtUserType) typeElement;
209                List<KtTypeProjection> typeArguments = userType.getTypeArguments();
210                for (KtTypeProjection typeArgument : typeArguments) {
211                    if (typeArgument.getProjectionKind() != KtProjectionKind.NONE) {
212                        trace.report(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE.on(typeArgument));
213                    }
214                }
215            }
216        }
217    
218        @NotNull
219        public static SimpleFunctionDescriptor createComponentFunctionDescriptor(
220                int parameterIndex,
221                @NotNull PropertyDescriptor property,
222                @NotNull ValueParameterDescriptor parameter,
223                @NotNull ClassDescriptor classDescriptor,
224                @NotNull BindingTrace trace
225        ) {
226            Name functionName = DataClassUtilsKt.createComponentName(parameterIndex);
227            KotlinType returnType = property.getType();
228    
229            SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
230                    classDescriptor,
231                    Annotations.Companion.getEMPTY(),
232                    functionName,
233                    CallableMemberDescriptor.Kind.SYNTHESIZED,
234                    parameter.getSource()
235            );
236    
237            functionDescriptor.initialize(
238                    null,
239                    classDescriptor.getThisAsReceiverParameter(),
240                    Collections.<TypeParameterDescriptor>emptyList(),
241                    Collections.<ValueParameterDescriptor>emptyList(),
242                    returnType,
243                    Modality.FINAL,
244                    property.getVisibility()
245            );
246            functionDescriptor.setOperator(true);
247    
248            trace.record(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter, functionDescriptor);
249    
250            return functionDescriptor;
251        }
252    
253        @NotNull
254        public static SimpleFunctionDescriptor createCopyFunctionDescriptor(
255                @NotNull Collection<ValueParameterDescriptor> constructorParameters,
256                @NotNull ClassDescriptor classDescriptor,
257                @NotNull BindingTrace trace
258        ) {
259            KotlinType returnType = classDescriptor.getDefaultType();
260    
261            SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
262                    classDescriptor,
263                    Annotations.Companion.getEMPTY(),
264                    COPY_METHOD_NAME,
265                    CallableMemberDescriptor.Kind.SYNTHESIZED,
266                    classDescriptor.getSource()
267            );
268    
269            List<ValueParameterDescriptor> parameterDescriptors = Lists.newArrayList();
270    
271            for (ValueParameterDescriptor parameter : constructorParameters) {
272                PropertyDescriptor propertyDescriptor = trace.getBindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
273                // If parameter hasn't corresponding property, so it mustn't have default value as a parameter in copy function for data class
274                boolean declaresDefaultValue = propertyDescriptor != null;
275                ValueParameterDescriptorImpl parameterDescriptor =
276                        new ValueParameterDescriptorImpl(functionDescriptor, null, parameter.getIndex(), parameter.getAnnotations(),
277                                                         parameter.getName(), parameter.getType(),
278                                                         declaresDefaultValue,
279                                                         parameter.isCrossinline(),
280                                                         parameter.isNoinline(),
281                                                         parameter.getVarargElementType(), parameter.getSource());
282                parameterDescriptors.add(parameterDescriptor);
283                if (declaresDefaultValue) {
284                    trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameterDescriptor, propertyDescriptor);
285                }
286            }
287    
288            functionDescriptor.initialize(
289                    null,
290                    classDescriptor.getThisAsReceiverParameter(),
291                    Collections.<TypeParameterDescriptor>emptyList(),
292                    parameterDescriptors,
293                    returnType,
294                    Modality.FINAL,
295                    Visibilities.PUBLIC
296            );
297    
298            trace.record(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor, functionDescriptor);
299            return functionDescriptor;
300        }
301    
302        public static Visibility getDefaultVisibility(KtModifierListOwner modifierListOwner, DeclarationDescriptor containingDescriptor) {
303            Visibility defaultVisibility;
304            if (containingDescriptor instanceof ClassDescriptor) {
305                KtModifierList modifierList = modifierListOwner.getModifierList();
306                defaultVisibility = modifierList != null && modifierList.hasModifier(OVERRIDE_KEYWORD)
307                                               ? Visibilities.INHERITED
308                                               : Visibilities.DEFAULT_VISIBILITY;
309            }
310            else if (containingDescriptor instanceof FunctionDescriptor || containingDescriptor instanceof PropertyDescriptor) {
311                defaultVisibility = Visibilities.LOCAL;
312            }
313            else {
314                defaultVisibility = Visibilities.DEFAULT_VISIBILITY;
315            }
316            return defaultVisibility;
317        }
318    
319        public static Modality getDefaultModality(DeclarationDescriptor containingDescriptor, Visibility visibility, boolean isBodyPresent) {
320            Modality defaultModality;
321            if (containingDescriptor instanceof ClassDescriptor) {
322                boolean isTrait = ((ClassDescriptor) containingDescriptor).getKind() == ClassKind.INTERFACE;
323                boolean isDefinitelyAbstract = isTrait && !isBodyPresent;
324                Modality basicModality = isTrait && !Visibilities.isPrivate(visibility) ? Modality.OPEN : Modality.FINAL;
325                defaultModality = isDefinitelyAbstract ? Modality.ABSTRACT : basicModality;
326            }
327            else {
328                defaultModality = Modality.FINAL;
329            }
330            return defaultModality;
331        }
332    
333        @NotNull
334        public ValueParameterDescriptorImpl resolveValueParameterDescriptor(
335                LexicalScope scope, FunctionDescriptor owner, KtParameter valueParameter, int index, KotlinType type, BindingTrace trace
336        ) {
337            KotlinType varargElementType = null;
338            KotlinType variableType = type;
339            if (valueParameter.hasModifier(VARARG_KEYWORD)) {
340                varargElementType = type;
341                variableType = getVarargParameterType(type);
342            }
343    
344            KtModifierList modifierList = valueParameter.getModifierList();
345    
346            Annotations allAnnotations =
347                    annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace);
348            Annotations valueParameterAnnotations = Annotations.Companion.getEMPTY();
349    
350            if (modifierList != null) {
351                if (valueParameter.hasValOrVar()) {
352                    AnnotationSplitter annotationSplitter = AnnotationSplitter.create(
353                            storageManager, allAnnotations, SetsKt.setOf(CONSTRUCTOR_PARAMETER));
354                    valueParameterAnnotations = annotationSplitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER);
355                }
356                else {
357                    valueParameterAnnotations = allAnnotations;
358                }
359            }
360    
361            ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
362                    owner,
363                    null,
364                    index,
365                    valueParameterAnnotations,
366                    KtPsiUtil.safeName(valueParameter.getName()),
367                    variableType,
368                    valueParameter.hasDefaultValue(),
369                    valueParameter.hasModifier(CROSSINLINE_KEYWORD),
370                    valueParameter.hasModifier(NOINLINE_KEYWORD),
371                    varargElementType,
372                    KotlinSourceElementKt.toSourceElement(valueParameter)
373            );
374    
375            trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
376            return valueParameterDescriptor;
377        }
378    
379        @NotNull
380        private KotlinType getVarargParameterType(@NotNull KotlinType elementType) {
381            KotlinType primitiveArrayType = builtIns.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(elementType);
382            if (primitiveArrayType != null) {
383                return primitiveArrayType;
384            }
385            return builtIns.getArrayType(Variance.OUT_VARIANCE, elementType);
386        }
387    
388        public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor(
389                DeclarationDescriptor containingDescriptor,
390                LexicalWritableScope extensibleScope,
391                LexicalScope scopeForAnnotationsResolve,
392                List<KtTypeParameter> typeParameters,
393                BindingTrace trace
394        ) {
395            List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
396            for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
397                KtTypeParameter typeParameter = typeParameters.get(i);
398                result.add(resolveTypeParameterForCallableDescriptor(
399                        containingDescriptor, extensibleScope, scopeForAnnotationsResolve, typeParameter, i, trace));
400            }
401            return result;
402        }
403    
404        private TypeParameterDescriptorImpl resolveTypeParameterForCallableDescriptor(
405                DeclarationDescriptor containingDescriptor,
406                LexicalWritableScope extensibleScope,
407                LexicalScope scopeForAnnotationsResolve,
408                final KtTypeParameter typeParameter,
409                int index,
410                final BindingTrace trace
411        ) {
412            if (typeParameter.getVariance() != Variance.INVARIANT) {
413                assert !(containingDescriptor instanceof ClassifierDescriptor) : "This method is intended for functions/properties";
414                trace.report(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY.on(typeParameter));
415            }
416    
417            Annotations annotations =
418                    annotationResolver.resolveAnnotationsWithArguments(scopeForAnnotationsResolve, typeParameter.getModifierList(), trace);
419    
420            TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
421                    containingDescriptor,
422                    annotations,
423                    typeParameter.hasModifier(KtTokens.REIFIED_KEYWORD),
424                    typeParameter.getVariance(),
425                    KtPsiUtil.safeName(typeParameter.getName()),
426                    index,
427                    KotlinSourceElementKt.toSourceElement(typeParameter),
428                    new Function1<KotlinType, Void>() {
429                        @Override
430                        public Void invoke(KotlinType type) {
431                            trace.report(Errors.CYCLIC_GENERIC_UPPER_BOUND.on(typeParameter));
432                            return null;
433                        }
434                    },
435                    supertypeLoopsResolver
436                    );
437            trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
438            extensibleScope.addClassifierDescriptor(typeParameterDescriptor);
439            return typeParameterDescriptor;
440        }
441    
442        @NotNull
443        public static ConstructorDescriptorImpl createAndRecordPrimaryConstructorForObject(
444                @Nullable KtClassOrObject object,
445                @NotNull ClassDescriptor classDescriptor,
446                @NotNull BindingTrace trace
447        ) {
448            ConstructorDescriptorImpl constructorDescriptor =
449                    DescriptorFactory.createPrimaryConstructorForObject(classDescriptor, KotlinSourceElementKt.toSourceElement(object));
450            if (object != null) {
451                KtPrimaryConstructor primaryConstructor = object.getPrimaryConstructor();
452                trace.record(CONSTRUCTOR, primaryConstructor != null ? primaryConstructor : object, constructorDescriptor);
453            }
454            return constructorDescriptor;
455        }
456    
457        static final class UpperBoundCheckRequest {
458            public final Name typeParameterName;
459            public final KtTypeReference upperBound;
460            public final KotlinType upperBoundType;
461    
462            UpperBoundCheckRequest(Name typeParameterName, KtTypeReference upperBound, KotlinType upperBoundType) {
463                this.typeParameterName = typeParameterName;
464                this.upperBound = upperBound;
465                this.upperBoundType = upperBoundType;
466            }
467        }
468    
469        public void resolveGenericBounds(
470                @NotNull KtTypeParameterListOwner declaration,
471                @NotNull DeclarationDescriptor descriptor,
472                LexicalScope scope,
473                List<TypeParameterDescriptorImpl> parameters,
474                BindingTrace trace
475        ) {
476            List<UpperBoundCheckRequest> upperBoundCheckRequests = Lists.newArrayList();
477    
478            List<KtTypeParameter> typeParameters = declaration.getTypeParameters();
479            Map<Name, TypeParameterDescriptorImpl> parameterByName = Maps.newHashMap();
480            for (int i = 0; i < typeParameters.size(); i++) {
481                KtTypeParameter ktTypeParameter = typeParameters.get(i);
482                TypeParameterDescriptorImpl typeParameterDescriptor = parameters.get(i);
483    
484                parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
485    
486                KtTypeReference extendsBound = ktTypeParameter.getExtendsBound();
487                if (extendsBound != null) {
488                    KotlinType type = typeResolver.resolveType(scope, extendsBound, trace, false);
489                    typeParameterDescriptor.addUpperBound(type);
490                    upperBoundCheckRequests.add(new UpperBoundCheckRequest(ktTypeParameter.getNameAsName(), extendsBound, type));
491                }
492            }
493            for (KtTypeConstraint constraint : declaration.getTypeConstraints()) {
494                KtSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName();
495                if (subjectTypeParameterName == null) {
496                    continue;
497                }
498                Name referencedName = subjectTypeParameterName.getReferencedNameAsName();
499                TypeParameterDescriptorImpl typeParameterDescriptor = parameterByName.get(referencedName);
500                KtTypeReference boundTypeReference = constraint.getBoundTypeReference();
501                KotlinType bound = null;
502                if (boundTypeReference != null) {
503                    bound = typeResolver.resolveType(scope, boundTypeReference, trace, false);
504                    upperBoundCheckRequests.add(new UpperBoundCheckRequest(referencedName, boundTypeReference, bound));
505                }
506    
507                if (typeParameterDescriptor != null) {
508                    trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
509                    if (bound != null) {
510                        typeParameterDescriptor.addUpperBound(bound);
511                    }
512                }
513            }
514    
515            for (TypeParameterDescriptorImpl parameter : parameters) {
516                parameter.addDefaultUpperBound();
517                parameter.setInitialized();
518            }
519    
520            for (TypeParameterDescriptorImpl parameter : parameters) {
521                checkConflictingUpperBounds(trace, parameter, typeParameters.get(parameter.getIndex()));
522            }
523    
524            if (!(declaration instanceof KtClass)) {
525                checkUpperBoundTypes(trace, upperBoundCheckRequests);
526                checkNamesInConstraints(declaration, descriptor, scope, trace);
527            }
528        }
529    
530        public static void checkUpperBoundTypes(@NotNull BindingTrace trace, @NotNull List<UpperBoundCheckRequest> requests) {
531            if (requests.isEmpty()) return;
532    
533            Set<Name> classBoundEncountered = new HashSet<Name>();
534            Set<Pair<Name, TypeConstructor>> allBounds = new HashSet<Pair<Name, TypeConstructor>>();
535    
536            for (UpperBoundCheckRequest request : requests) {
537                Name typeParameterName = request.typeParameterName;
538                KotlinType upperBound = request.upperBoundType;
539                KtTypeReference upperBoundElement = request.upperBound;
540    
541                if (!upperBound.isError()) {
542                    if (!allBounds.add(new Pair<Name, TypeConstructor>(typeParameterName, upperBound.getConstructor()))) {
543                        trace.report(REPEATED_BOUND.on(upperBoundElement));
544                    }
545                    else {
546                        ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(upperBound);
547                        if (classDescriptor != null) {
548                            ClassKind kind = classDescriptor.getKind();
549                            if (kind == ClassKind.CLASS || kind == ClassKind.ENUM_CLASS || kind == ClassKind.OBJECT) {
550                                if (!classBoundEncountered.add(typeParameterName)) {
551                                    trace.report(ONLY_ONE_CLASS_BOUND_ALLOWED.on(upperBoundElement));
552                                }
553                            }
554                        }
555                    }
556                }
557    
558                checkUpperBoundType(upperBoundElement, upperBound, trace);
559            }
560        }
561    
562        public static void checkConflictingUpperBounds(
563                @NotNull BindingTrace trace,
564                @NotNull TypeParameterDescriptor parameter,
565                @NotNull KtTypeParameter typeParameter
566        ) {
567            if (KotlinBuiltIns.isNothing(TypeIntersector.getUpperBoundsAsType(parameter))) {
568                trace.report(CONFLICTING_UPPER_BOUNDS.on(typeParameter, parameter));
569            }
570        }
571    
572        public void checkNamesInConstraints(
573                @NotNull KtTypeParameterListOwner declaration,
574                @NotNull DeclarationDescriptor descriptor,
575                @NotNull LexicalScope scope,
576                @NotNull BindingTrace trace
577        ) {
578            for (KtTypeConstraint constraint : declaration.getTypeConstraints()) {
579                KtSimpleNameExpression nameExpression = constraint.getSubjectTypeParameterName();
580                if (nameExpression == null) continue;
581    
582                Name name = nameExpression.getReferencedNameAsName();
583    
584                ClassifierDescriptor classifier = ScopeUtilsKt.findClassifier(scope, name, NoLookupLocation.FOR_NON_TRACKED_SCOPE);
585                if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == descriptor) continue;
586    
587                if (classifier != null) {
588                    // To tell the user that we look only for locally defined type parameters
589                    trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(nameExpression, constraint, declaration));
590                    trace.record(BindingContext.REFERENCE_TARGET, nameExpression, classifier);
591                }
592                else {
593                    trace.report(UNRESOLVED_REFERENCE.on(nameExpression, nameExpression));
594                }
595    
596                KtTypeReference boundTypeReference = constraint.getBoundTypeReference();
597                if (boundTypeReference != null) {
598                    typeResolver.resolveType(scope, boundTypeReference, trace, true);
599                }
600            }
601        }
602    
603        public static void checkUpperBoundType(
604                KtTypeReference upperBound,
605                @NotNull KotlinType upperBoundType,
606                BindingTrace trace
607        ) {
608            if (DeclarationsCheckerKt.checkNotEnumEntry(upperBound, trace)) return;
609            if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, upperBoundType)) {
610                trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
611            }
612            if (DynamicTypesKt.isDynamic(upperBoundType)) {
613                trace.report(DYNAMIC_UPPER_BOUND.on(upperBound));
614            }
615            if (FunctionTypesKt.isExtensionFunctionType(upperBoundType)) {
616                trace.report(UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE.on(upperBound));
617            }
618        }
619    
620        @NotNull
621        public VariableDescriptor resolveLocalVariableDescriptor(
622                @NotNull LexicalScope scope,
623                @NotNull KtParameter parameter,
624                BindingTrace trace
625        ) {
626            KotlinType type = resolveParameterType(scope, parameter, trace);
627            return resolveLocalVariableDescriptor(parameter, type, trace, scope);
628        }
629    
630        private KotlinType resolveParameterType(LexicalScope scope, KtParameter parameter, BindingTrace trace) {
631            KtTypeReference typeReference = parameter.getTypeReference();
632            KotlinType type;
633            if (typeReference != null) {
634                type = typeResolver.resolveType(scope, typeReference, trace, true);
635            }
636            else {
637                // Error is reported by the parser
638                type = ErrorUtils.createErrorType("Annotation is absent");
639            }
640            if (parameter.hasModifier(VARARG_KEYWORD)) {
641                return getVarargParameterType(type);
642            }
643            return type;
644        }
645    
646        public VariableDescriptor resolveLocalVariableDescriptor(
647                @NotNull KtParameter parameter,
648                @NotNull KotlinType type,
649                BindingTrace trace,
650                @NotNull LexicalScope scope
651        ) {
652            VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
653                    scope.getOwnerDescriptor(),
654                    annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
655                    KtPsiUtil.safeName(parameter.getName()),
656                    type,
657                    false,
658                    KotlinSourceElementKt.toSourceElement(parameter)
659            );
660            trace.record(BindingContext.VALUE_PARAMETER, parameter, variableDescriptor);
661            // Type annotations also should be resolved
662            ForceResolveUtil.forceResolveAllContents(type.getAnnotations());
663            return variableDescriptor;
664        }
665    
666        @NotNull
667        public PropertyDescriptor resolvePropertyDescriptor(
668                @NotNull DeclarationDescriptor containingDeclaration,
669                @NotNull LexicalScope scope,
670                @NotNull KtProperty property,
671                @NotNull final BindingTrace trace,
672                @NotNull DataFlowInfo dataFlowInfo
673        ) {
674            KtModifierList modifierList = property.getModifierList();
675            boolean isVar = property.isVar();
676    
677            boolean hasBody = hasBody(property);
678            Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
679            Modality modality = containingDeclaration instanceof ClassDescriptor
680                                ? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody))
681                                : Modality.FINAL;
682    
683            final AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper(property);
684    
685            Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace);
686            AnnotationSplitter annotationSplitter =
687                    new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {
688                @Override
689                public Set<AnnotationUseSiteTarget> invoke() {
690                    return AnnotationSplitter.getTargetSet(false, trace.getBindingContext(), wrapper);
691                }
692            });
693    
694            Annotations propertyAnnotations = new CompositeAnnotations(CollectionsKt.listOf(
695                    annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD, PROPERTY_DELEGATE_FIELD),
696                    annotationSplitter.getOtherAnnotations()));
697    
698            PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
699                    containingDeclaration,
700                    propertyAnnotations,
701                    modality,
702                    visibility,
703                    isVar,
704                    KtPsiUtil.safeName(property.getName()),
705                    CallableMemberDescriptor.Kind.DECLARATION,
706                    KotlinSourceElementKt.toSourceElement(property),
707                    modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD),
708                    modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD)
709            );
710            wrapper.setDescriptor(propertyDescriptor);
711    
712            List<TypeParameterDescriptorImpl> typeParameterDescriptors;
713            LexicalScope scopeWithTypeParameters;
714            KotlinType receiverType = null;
715    
716            {
717                List<KtTypeParameter> typeParameters = property.getTypeParameters();
718                if (typeParameters.isEmpty()) {
719                    scopeWithTypeParameters = scope;
720                    typeParameterDescriptors = Collections.emptyList();
721                }
722                else {
723                    LexicalWritableScope writableScope = new LexicalWritableScope(
724                            scope, containingDeclaration, false, null, new TraceBasedLocalRedeclarationChecker(trace),
725                            LexicalScopeKind.PROPERTY_HEADER);
726                    typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(
727                            propertyDescriptor, writableScope, scope, typeParameters, trace);
728                    writableScope.freeze();
729                    resolveGenericBounds(property, propertyDescriptor, writableScope, typeParameterDescriptors, trace);
730                    scopeWithTypeParameters = writableScope;
731                }
732    
733                KtTypeReference receiverTypeRef = property.getReceiverTypeReference();
734                if (receiverTypeRef != null) {
735                    receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef, trace, true);
736                }
737            }
738    
739            ReceiverParameterDescriptor receiverDescriptor =
740                    DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
741    
742            KotlinType type = variableTypeResolver.process(
743                    propertyDescriptor, ScopeUtils.makeScopeForPropertyInitializer(scopeWithTypeParameters, propertyDescriptor),
744                    property, dataFlowInfo, true, trace
745            );
746    
747            propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
748                                       receiverDescriptor);
749    
750            PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
751                    scopeWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace);
752            PropertySetterDescriptor setter = resolvePropertySetterDescriptor(
753                    scopeWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace);
754    
755            propertyDescriptor.initialize(getter, setter);
756    
757            trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
758            return propertyDescriptor;
759        }
760    
761        /*package*/
762        static boolean hasBody(KtProperty property) {
763            boolean hasBody = property.hasDelegateExpressionOrInitializer();
764            if (!hasBody) {
765                KtPropertyAccessor getter = property.getGetter();
766                if (getter != null && getter.hasBody()) {
767                    hasBody = true;
768                }
769                KtPropertyAccessor setter = property.getSetter();
770                if (!hasBody && setter != null && setter.hasBody()) {
771                    hasBody = true;
772                }
773            }
774            return hasBody;
775        }
776    
777    
778        @Nullable
779        /*package*/ static KotlinType transformAnonymousTypeIfNeeded(
780                @NotNull DeclarationDescriptorWithVisibility descriptor,
781                @NotNull KtDeclaration declaration,
782                @NotNull KotlinType type,
783                @NotNull BindingTrace trace
784        ) {
785            ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
786            if (classifier == null || !DescriptorUtils.isAnonymousObject(classifier) || DescriptorUtils.isLocal(descriptor)) {
787                return type;
788            }
789    
790            boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null;
791            if (!definedInClass || !Visibilities.isPrivate(descriptor.getVisibility())) {
792                if (type.getConstructor().getSupertypes().size() == 1) {
793                    return type.getConstructor().getSupertypes().iterator().next();
794                }
795                else {
796                    trace.report(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED.on(declaration, type.getConstructor().getSupertypes()));
797                }
798            }
799    
800            return type;
801        }
802    
803    
804        @Nullable
805        private PropertySetterDescriptor resolvePropertySetterDescriptor(
806                @NotNull LexicalScope scopeWithTypeParameters,
807                @NotNull KtProperty property,
808                @NotNull PropertyDescriptor propertyDescriptor,
809                @NotNull AnnotationSplitter annotationSplitter,
810                BindingTrace trace
811        ) {
812            KtPropertyAccessor setter = property.getSetter();
813            PropertySetterDescriptorImpl setterDescriptor = null;
814            if (setter != null) {
815                Annotations annotations = new CompositeAnnotations(CollectionsKt.listOf(
816                        annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER),
817                        annotationResolver.resolveAnnotationsWithoutArguments(scopeWithTypeParameters, setter.getModifierList(), trace)));
818                KtParameter parameter = setter.getParameter();
819    
820                setterDescriptor = new PropertySetterDescriptorImpl(
821                        propertyDescriptor, annotations,
822                        resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
823                        resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
824                        /* isDefault = */ false, setter.hasModifier(EXTERNAL_KEYWORD),
825                        CallableMemberDescriptor.Kind.DECLARATION, null, KotlinSourceElementKt.toSourceElement(setter)
826                );
827                KtTypeReference returnTypeReference = setter.getReturnTypeReference();
828                if (returnTypeReference != null) {
829                    KotlinType returnType = typeResolver.resolveType(scopeWithTypeParameters, returnTypeReference, trace, true);
830                    if (!KotlinBuiltIns.isUnit(returnType)) {
831                        trace.report(WRONG_SETTER_RETURN_TYPE.on(returnTypeReference));
832                    }
833                }
834    
835                if (parameter != null) {
836    
837                    // This check is redundant: the parser does not allow a default value, but we'll keep it just in case
838                    if (parameter.hasDefaultValue()) {
839                        trace.report(SETTER_PARAMETER_WITH_DEFAULT_VALUE.on(parameter.getDefaultValue()));
840                    }
841    
842                    KotlinType type;
843                    KtTypeReference typeReference = parameter.getTypeReference();
844                    if (typeReference == null) {
845                        type = propertyDescriptor.getType(); // TODO : this maybe unknown at this point
846                    }
847                    else {
848                        type = typeResolver.resolveType(scopeWithTypeParameters, typeReference, trace, true);
849                        KotlinType inType = propertyDescriptor.getType();
850                        if (inType != null) {
851                            if (!TypeUtils.equalTypes(type, inType)) {
852                                trace.report(WRONG_SETTER_PARAMETER_TYPE.on(typeReference, inType, type));
853                            }
854                        }
855                        else {
856                            // TODO : the same check may be needed later???
857                        }
858                    }
859    
860                    ValueParameterDescriptorImpl valueParameterDescriptor =
861                            resolveValueParameterDescriptor(scopeWithTypeParameters, setterDescriptor, parameter, 0, type, trace);
862                    setterDescriptor.initialize(valueParameterDescriptor);
863                }
864                else {
865                    setterDescriptor.initializeDefault();
866                }
867    
868                trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
869            }
870            else if (property.isVar()) {
871                Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
872                setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, setterAnnotations, !property.hasDelegate(),
873                                                                  /* isExternal = */ false, propertyDescriptor.getSource());
874            }
875    
876            if (!property.isVar()) {
877                if (setter != null) {
878                    //                trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
879                    trace.report(VAL_WITH_SETTER.on(setter));
880                }
881            }
882            return setterDescriptor;
883        }
884    
885        @NotNull
886        private PropertyGetterDescriptorImpl resolvePropertyGetterDescriptor(
887                @NotNull LexicalScope scopeWithTypeParameters,
888                @NotNull KtProperty property,
889                @NotNull PropertyDescriptor propertyDescriptor,
890                @NotNull AnnotationSplitter annotationSplitter,
891                BindingTrace trace
892        ) {
893            PropertyGetterDescriptorImpl getterDescriptor;
894            KtPropertyAccessor getter = property.getGetter();
895            if (getter != null) {
896                Annotations getterAnnotations = new CompositeAnnotations(CollectionsKt.listOf(
897                        annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER),
898                        annotationResolver.resolveAnnotationsWithoutArguments(scopeWithTypeParameters, getter.getModifierList(), trace)));
899    
900                getterDescriptor = new PropertyGetterDescriptorImpl(
901                        propertyDescriptor, getterAnnotations,
902                        resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
903                        resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
904                        /* isDefault = */ false, getter.hasModifier(EXTERNAL_KEYWORD),
905                        CallableMemberDescriptor.Kind.DECLARATION, null, KotlinSourceElementKt.toSourceElement(getter)
906                );
907                KotlinType returnType =
908                        determineGetterReturnType(scopeWithTypeParameters, trace, getterDescriptor, getter, propertyDescriptor.getType());
909                getterDescriptor.initialize(returnType);
910                trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
911            }
912            else {
913                Annotations getterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER);
914                getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, getterAnnotations, !property.hasDelegate(),
915                                                                  /* isExternal = */ false);
916                getterDescriptor.initialize(propertyDescriptor.getType());
917            }
918            return getterDescriptor;
919        }
920    
921        @NotNull
922        private KotlinType determineGetterReturnType(
923                @NotNull LexicalScope scope,
924                @NotNull BindingTrace trace,
925                @NotNull PropertyGetterDescriptor getterDescriptor,
926                @NotNull KtPropertyAccessor getter,
927                @NotNull KotlinType propertyType
928        ) {
929            KtTypeReference returnTypeReference = getter.getReturnTypeReference();
930            if (returnTypeReference != null) {
931                KotlinType explicitReturnType = typeResolver.resolveType(scope, returnTypeReference, trace, true);
932                if (!TypeUtils.equalTypes(explicitReturnType, propertyType)) {
933                    trace.report(WRONG_GETTER_RETURN_TYPE.on(returnTypeReference, propertyType, explicitReturnType));
934                }
935                return explicitReturnType;
936            }
937    
938            // If a property has no type specified in the PSI but the getter does (or has an initializer e.g. "val x get() = ..."),
939            // infer the correct type for the getter but leave the error type for the property.
940            // This is useful for an IDE quick fix which would add the type to the property
941            KtProperty property = getter.getProperty();
942            if (!property.hasDelegateExpressionOrInitializer() && property.getTypeReference() == null &&
943                getter.hasBody() && !getter.hasBlockBody()) {
944                return inferReturnTypeFromExpressionBody(
945                        storageManager, expressionTypingServices, trace, scope, DataFlowInfoFactory.EMPTY, getter, getterDescriptor
946                );
947            }
948    
949            return propertyType;
950        }
951    
952        @NotNull
953        /*package*/ static DeferredType inferReturnTypeFromExpressionBody(
954                @NotNull StorageManager storageManager,
955                @NotNull final ExpressionTypingServices expressionTypingServices,
956                @NotNull final BindingTrace trace,
957                @NotNull final LexicalScope scope,
958                @NotNull final DataFlowInfo dataFlowInfo,
959                @NotNull final KtDeclarationWithBody function,
960                @NotNull final FunctionDescriptor functionDescriptor
961        ) {
962            return DeferredType.createRecursionIntolerant(storageManager, trace, new Function0<KotlinType>() {
963                @Override
964                public KotlinType invoke() {
965                    PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace);
966                    KotlinType type = expressionTypingServices.getBodyExpressionType(
967                            trace, scope, dataFlowInfo, function, functionDescriptor);
968                    return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
969                }
970            });
971        }
972    
973        @NotNull
974        public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
975                @NotNull ClassDescriptor classDescriptor,
976                @NotNull ValueParameterDescriptor valueParameter,
977                @NotNull LexicalScope scope,
978                @NotNull KtParameter parameter, final BindingTrace trace
979        ) {
980            KotlinType type = resolveParameterType(scope, parameter, trace);
981            Name name = parameter.getNameAsSafeName();
982            boolean isMutable = parameter.isMutable();
983            KtModifierList modifierList = parameter.getModifierList();
984    
985            if (modifierList != null) {
986                if (modifierList.hasModifier(KtTokens.ABSTRACT_KEYWORD)) {
987                    trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(parameter));
988                }
989            }
990    
991            final AnnotationSplitter.PropertyWrapper propertyWrapper = new AnnotationSplitter.PropertyWrapper(parameter);
992            Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, parameter.getModifierList(), trace);
993            AnnotationSplitter annotationSplitter =
994                    new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {
995                        @Override
996                        public Set<AnnotationUseSiteTarget> invoke() {
997                            return AnnotationSplitter.getTargetSet(true, trace.getBindingContext(), propertyWrapper);
998                        }
999                    });
1000    
1001            Annotations propertyAnnotations = new CompositeAnnotations(
1002                    annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD),
1003                    annotationSplitter.getOtherAnnotations());
1004    
1005            PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
1006                    classDescriptor,
1007                    propertyAnnotations,
1008                    resolveModalityFromModifiers(parameter, Modality.FINAL),
1009                    resolveVisibilityFromModifiers(parameter, getDefaultVisibility(parameter, classDescriptor)),
1010                    isMutable,
1011                    name,
1012                    CallableMemberDescriptor.Kind.DECLARATION,
1013                    KotlinSourceElementKt.toSourceElement(parameter),
1014                    /* lateInit = */ false,
1015                    /* isConst = */ false
1016            );
1017            propertyWrapper.setDescriptor(propertyDescriptor);
1018            propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
1019                                       getDispatchReceiverParameterIfNeeded(classDescriptor), (ReceiverParameterDescriptor) null);
1020    
1021            Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
1022            Annotations getterAnnotations = new CompositeAnnotations(CollectionsKt.listOf(
1023                    annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER)));
1024    
1025            PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, getterAnnotations);
1026            PropertySetterDescriptor setter =
1027                    propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor, setterAnnotations) : null;
1028    
1029            propertyDescriptor.initialize(getter, setter);
1030            getter.initialize(propertyDescriptor.getType());
1031    
1032            trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
1033            trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
1034            return propertyDescriptor;
1035        }
1036    
1037        public static void checkBounds(@NotNull KtTypeReference typeReference, @NotNull KotlinType type, @NotNull BindingTrace trace) {
1038            if (type.isError()) return;
1039    
1040            KtTypeElement typeElement = typeReference.getTypeElement();
1041            if (typeElement == null) return;
1042    
1043            List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
1044            List<TypeProjection> arguments = type.getArguments();
1045            assert parameters.size() == arguments.size();
1046    
1047            List<KtTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
1048    
1049            // A type reference from Kotlin code can yield a flexible type only if it's `ft<T1, T2>`, whose bounds should not be checked
1050            if (FlexibleTypesKt.isFlexible(type) && !DynamicTypesKt.isDynamic(type)) {
1051                assert jetTypeArguments.size() == 2
1052                        : "Flexible type cannot be denoted in Kotlin otherwise than as ft<T1, T2>, but was: "
1053                          + PsiUtilsKt.getElementTextWithContext(typeReference);
1054                // it's really ft<Foo, Bar>
1055                Flexibility flexibility = FlexibleTypesKt.flexibility(type);
1056                checkBounds(jetTypeArguments.get(0), flexibility.getLowerBound(), trace);
1057                checkBounds(jetTypeArguments.get(1), flexibility.getUpperBound(), trace);
1058                return;
1059            }
1060    
1061            assert jetTypeArguments.size() <= arguments.size() : typeElement.getText() + ": " + jetTypeArguments + " - " + arguments;
1062    
1063            TypeSubstitutor substitutor = TypeSubstitutor.create(type);
1064            for (int i = 0; i < jetTypeArguments.size(); i++) {
1065                KtTypeReference jetTypeArgument = jetTypeArguments.get(i);
1066    
1067                if (jetTypeArgument == null) continue;
1068    
1069                KotlinType typeArgument = arguments.get(i).getType();
1070                checkBounds(jetTypeArgument, typeArgument, trace);
1071    
1072                TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
1073                checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace);
1074            }
1075        }
1076    
1077        public static void checkBounds(
1078                @NotNull KtTypeReference jetTypeArgument,
1079                @NotNull KotlinType typeArgument,
1080                @NotNull TypeParameterDescriptor typeParameterDescriptor,
1081                @NotNull TypeSubstitutor substitutor,
1082                @NotNull BindingTrace trace
1083        ) {
1084            for (KotlinType bound : typeParameterDescriptor.getUpperBounds()) {
1085                KotlinType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
1086                if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(typeArgument, substitutedBound)) {
1087                    trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument));
1088                }
1089            }
1090        }
1091    
1092        public static boolean checkHasOuterClassInstance(
1093                @NotNull LexicalScope scope,
1094                @NotNull BindingTrace trace,
1095                @NotNull PsiElement reportErrorsOn,
1096                @NotNull ClassDescriptor target
1097        ) {
1098            ClassDescriptor classDescriptor = getContainingClass(scope);
1099    
1100            if (!isInsideOuterClassOrItsSubclass(classDescriptor, target)) {
1101                return true;
1102            }
1103    
1104            while (classDescriptor != null) {
1105                if (isSubclass(classDescriptor, target)) {
1106                    return true;
1107                }
1108    
1109                if (isStaticNestedClass(classDescriptor)) {
1110                    trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
1111                    return false;
1112                }
1113                classDescriptor = getParentOfType(classDescriptor, ClassDescriptor.class, true);
1114            }
1115            return true;
1116        }
1117    
1118        private static boolean isInsideOuterClassOrItsSubclass(@Nullable DeclarationDescriptor nested, @NotNull ClassDescriptor outer) {
1119            if (nested == null) return false;
1120    
1121            if (nested instanceof ClassDescriptor && isSubclass((ClassDescriptor) nested, outer)) return true;
1122    
1123            return isInsideOuterClassOrItsSubclass(nested.getContainingDeclaration(), outer);
1124        }
1125    
1126        @Nullable
1127        public static ClassDescriptor getContainingClass(@NotNull LexicalScope scope) {
1128            return getParentOfType(scope.getOwnerDescriptor(), ClassDescriptor.class, false);
1129        }
1130    
1131        public static void registerFileInPackage(@NotNull BindingTrace trace, @NotNull KtFile file) {
1132            // Register files corresponding to this package
1133            // The trace currently does not support bi-di multimaps that would handle this task nicer
1134            FqName fqName = file.getPackageFqName();
1135            Collection<KtFile> files = trace.get(PACKAGE_TO_FILES, fqName);
1136            if (files == null) {
1137                files = Sets.newIdentityHashSet();
1138            }
1139            files.add(file);
1140            trace.record(BindingContext.PACKAGE_TO_FILES, fqName, files);
1141        }
1142    }