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