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