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