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