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