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