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