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