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 void resolveMutableClassDescriptor(
112                @NotNull TopDownAnalysisParameters topDownAnalysisParameters,
113                @NotNull JetClass classElement,
114                @NotNull MutableClassDescriptor descriptor,
115                BindingTrace trace
116        ) {
117            // TODO : Where-clause
118            List<JetTypeParameter> typeParameters = classElement.getTypeParameters();
119            List<TypeParameterDescriptor> typeParameterDescriptors = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
120            if (descriptor.getKind() == ClassKind.ENUM_CLASS) {
121                JetTypeParameterList typeParameterList = classElement.getTypeParameterList();
122                if (typeParameterList != null) {
123                    trace.report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
124                }
125            }
126            int index = 0;
127            for (JetTypeParameter typeParameter : typeParameters) {
128                if (!topDownAnalysisParameters.isLazy()) {
129                    // TODO: Support
130                    AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, trace);
131                }
132    
133                TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
134                        descriptor,
135                        Annotations.EMPTY,
136                        typeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
137                        typeParameter.getVariance(),
138                        JetPsiUtil.safeName(typeParameter.getName()),
139                        index,
140                        toSourceElement(typeParameter)
141                );
142                trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
143                typeParameterDescriptors.add(typeParameterDescriptor);
144                index++;
145            }
146            descriptor.setTypeParameterDescriptors(typeParameterDescriptors);
147            Modality defaultModality = descriptor.getKind() == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
148            descriptor.setModality(resolveModalityFromModifiers(classElement, defaultModality));
149            descriptor.setVisibility(resolveVisibilityFromModifiers(classElement, getDefaultClassVisibility(descriptor)));
150    
151            trace.record(BindingContext.CLASS, classElement, descriptor);
152        }
153    
154        public void resolveSupertypesForMutableClassDescriptor(
155                @NotNull JetClassOrObject jetClass,
156                @NotNull MutableClassDescriptor descriptor,
157                BindingTrace trace
158        ) {
159            for (JetType supertype : resolveSupertypes(descriptor.getScopeForClassHeaderResolution(), descriptor, jetClass, trace)) {
160                descriptor.addSupertype(supertype);
161            }
162        }
163    
164        public List<JetType> resolveSupertypes(
165                @NotNull JetScope scope,
166                @NotNull ClassDescriptor classDescriptor,
167                @NotNull JetClassOrObject jetClass,
168                BindingTrace trace
169        ) {
170            List<JetType> supertypes = Lists.newArrayList();
171            List<JetDelegationSpecifier> delegationSpecifiers = jetClass.getDelegationSpecifiers();
172            Collection<JetType> declaredSupertypes = resolveDelegationSpecifiers(
173                    scope,
174                    delegationSpecifiers,
175                    typeResolver, trace, false);
176    
177            for (JetType declaredSupertype : declaredSupertypes) {
178                addValidSupertype(supertypes, declaredSupertype);
179            }
180    
181            if (classDescriptor.getKind() == ClassKind.ENUM_CLASS && !containsClass(supertypes)) {
182                supertypes.add(0, builtIns.getEnumType(classDescriptor.getDefaultType()));
183            }
184    
185            if (supertypes.isEmpty()) {
186                JetType defaultSupertype = getDefaultSupertype(jetClass, trace);
187                addValidSupertype(supertypes, defaultSupertype);
188            }
189    
190            return supertypes;
191        }
192    
193        private static void addValidSupertype(List<JetType> supertypes, JetType declaredSupertype) {
194            if (!declaredSupertype.isError()) {
195                supertypes.add(declaredSupertype);
196            }
197        }
198    
199        private boolean containsClass(Collection<JetType> result) {
200            for (JetType type : result) {
201                ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
202                if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.TRAIT) {
203                    return true;
204                }
205            }
206            return false;
207        }
208    
209        private JetType getDefaultSupertype(JetClassOrObject jetClass, BindingTrace trace) {
210            // TODO : beautify
211            if (jetClass instanceof JetEnumEntry) {
212                JetClassOrObject parent = JetStubbedPsiUtil.getContainingDeclaration(jetClass, JetClassOrObject.class);
213                ClassDescriptor parentDescriptor = trace.getBindingContext().get(BindingContext.CLASS, parent);
214                if (parentDescriptor.getTypeConstructor().getParameters().isEmpty()) {
215                    return parentDescriptor.getDefaultType();
216                }
217                else {
218                    trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(jetClass.getNameIdentifier()));
219                    return ErrorUtils.createErrorType("Supertype not specified");
220                }
221            }
222            else if (jetClass instanceof JetClass && ((JetClass) jetClass).isAnnotation()) {
223                return builtIns.getAnnotationType();
224            }
225            return builtIns.getAnyType();
226        }
227    
228        public Collection<JetType> resolveDelegationSpecifiers(
229                JetScope extensibleScope,
230                List<JetDelegationSpecifier> delegationSpecifiers,
231                @NotNull TypeResolver resolver,
232                BindingTrace trace,
233                boolean checkBounds
234        ) {
235            if (delegationSpecifiers.isEmpty()) {
236                return Collections.emptyList();
237            }
238            Collection<JetType> result = Lists.newArrayList();
239            for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
240                JetTypeReference typeReference = delegationSpecifier.getTypeReference();
241                if (typeReference != null) {
242                    JetType supertype = resolver.resolveType(extensibleScope, typeReference, trace, checkBounds);
243                    if (TypesPackage.isDynamic(supertype)) {
244                        trace.report(DYNAMIC_SUPERTYPE.on(typeReference));
245                    }
246                    else {
247                        result.add(supertype);
248                        JetTypeElement bareSuperType = checkNullableSupertypeAndStripQuestionMarks(trace, typeReference.getTypeElement());
249                        checkProjectionsInImmediateArguments(trace, bareSuperType);
250                    }
251                }
252                else {
253                    result.add(ErrorUtils.createErrorType("No type reference"));
254                }
255            }
256            return result;
257        }
258    
259        @Nullable
260        private static JetTypeElement checkNullableSupertypeAndStripQuestionMarks(@NotNull BindingTrace trace, @Nullable JetTypeElement typeElement) {
261            while (typeElement instanceof JetNullableType) {
262                JetNullableType nullableType = (JetNullableType) typeElement;
263                typeElement = nullableType.getInnerType();
264                // report only for innermost '?', the rest gets a 'redundant' warning
265                if (!(typeElement instanceof JetNullableType) && typeElement != null) {
266                    trace.report(NULLABLE_SUPERTYPE.on(nullableType));
267                }
268            }
269            return typeElement;
270        }
271    
272        private static void checkProjectionsInImmediateArguments(@NotNull BindingTrace trace, @Nullable JetTypeElement typeElement) {
273            if (typeElement instanceof JetUserType) {
274                JetUserType userType = (JetUserType) typeElement;
275                List<JetTypeProjection> typeArguments = userType.getTypeArguments();
276                for (JetTypeProjection typeArgument : typeArguments) {
277                    if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) {
278                        trace.report(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE.on(typeArgument));
279                    }
280                }
281            }
282        }
283    
284        @NotNull
285        public SimpleFunctionDescriptor resolveFunctionDescriptorWithAnnotationArguments(
286                @NotNull DeclarationDescriptor containingDescriptor,
287                @NotNull JetScope scope,
288                @NotNull JetNamedFunction function,
289                @NotNull BindingTrace trace,
290                @NotNull DataFlowInfo dataFlowInfo
291        ) {
292            return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
293                                             annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace));
294        }
295    
296        @NotNull
297        public SimpleFunctionDescriptor resolveFunctionDescriptor(
298                @NotNull DeclarationDescriptor containingDescriptor,
299                @NotNull JetScope scope,
300                @NotNull JetNamedFunction function,
301                @NotNull BindingTrace trace,
302                @NotNull DataFlowInfo dataFlowInfo
303        ) {
304           return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
305                                            annotationResolver.resolveAnnotationsWithoutArguments(scope, function.getModifierList(), trace));
306        }
307    
308        @NotNull
309        private SimpleFunctionDescriptor resolveFunctionDescriptor(
310                @NotNull DeclarationDescriptor containingDescriptor,
311                @NotNull final JetScope scope,
312                @NotNull final JetNamedFunction function,
313                @NotNull final BindingTrace trace,
314                @NotNull final DataFlowInfo dataFlowInfo,
315                @NotNull Annotations annotations
316        ) {
317            final SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
318                    containingDescriptor,
319                    annotations,
320                    JetPsiUtil.safeName(function.getName()),
321                    CallableMemberDescriptor.Kind.DECLARATION,
322                    toSourceElement(function)
323            );
324            WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace),
325                                                             "Function descriptor header scope");
326            innerScope.addLabeledDeclaration(functionDescriptor);
327    
328            List<TypeParameterDescriptorImpl> typeParameterDescriptors =
329                    resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, function.getTypeParameters(), trace);
330            innerScope.changeLockLevel(WritableScope.LockLevel.BOTH);
331            resolveGenericBounds(function, functionDescriptor, innerScope, typeParameterDescriptors, trace);
332    
333            JetType receiverType = null;
334            JetTypeReference receiverTypeRef = function.getReceiverTypeReference();
335            if (receiverTypeRef != null) {
336                JetScope scopeForReceiver =
337                        function.hasTypeParameterListBeforeFunctionName()
338                        ? innerScope
339                        : scope;
340                receiverType = typeResolver.resolveType(scopeForReceiver, receiverTypeRef, trace, true);
341            }
342    
343            List<ValueParameterDescriptor> valueParameterDescriptors =
344                    resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters(), trace);
345    
346            innerScope.changeLockLevel(WritableScope.LockLevel.READING);
347    
348            JetTypeReference returnTypeRef = function.getTypeReference();
349            JetType returnType;
350            if (returnTypeRef != null) {
351                returnType = typeResolver.resolveType(innerScope, returnTypeRef, trace, true);
352            }
353            else if (function.hasBlockBody()) {
354                returnType = builtIns.getUnitType();
355            }
356            else {
357                if (function.hasBody()) {
358                    returnType =
359                            DeferredType.createRecursionIntolerant(
360                                    storageManager,
361                                    trace,
362                                    new Function0<JetType>() {
363                                        @Override
364                                        public JetType invoke() {
365                                            JetType type = expressionTypingServices
366                                                    .getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
367                                            return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
368                                        }
369                                    });
370                }
371                else {
372                    returnType = ErrorUtils.createErrorType("No type, no body");
373                }
374            }
375            Modality modality = resolveModalityFromModifiers(function, getDefaultModality(containingDescriptor, function.hasBody()));
376            Visibility visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, containingDescriptor));
377            functionDescriptor.initialize(
378                    receiverType,
379                    getDispatchReceiverParameterIfNeeded(containingDescriptor),
380                    typeParameterDescriptors,
381                    valueParameterDescriptors,
382                    returnType,
383                    modality,
384                    visibility
385            );
386    
387            BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
388            return functionDescriptor;
389        }
390    
391        @NotNull
392        public static SimpleFunctionDescriptor createComponentFunctionDescriptor(
393                int parameterIndex,
394                @NotNull PropertyDescriptor property,
395                @NotNull ValueParameterDescriptor parameter,
396                @NotNull ClassDescriptor classDescriptor,
397                @NotNull BindingTrace trace
398        ) {
399            Name functionName = DataClassUtilsPackage.createComponentName(parameterIndex);
400            JetType returnType = property.getType();
401    
402            SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
403                    classDescriptor,
404                    Annotations.EMPTY,
405                    functionName,
406                    CallableMemberDescriptor.Kind.SYNTHESIZED,
407                    parameter.getSource()
408            );
409    
410            functionDescriptor.initialize(
411                    null,
412                    classDescriptor.getThisAsReceiverParameter(),
413                    Collections.<TypeParameterDescriptor>emptyList(),
414                    Collections.<ValueParameterDescriptor>emptyList(),
415                    returnType,
416                    Modality.FINAL,
417                    property.getVisibility()
418            );
419    
420            trace.record(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter, functionDescriptor);
421    
422            return functionDescriptor;
423        }
424    
425        @NotNull
426        public static SimpleFunctionDescriptor createCopyFunctionDescriptor(
427                @NotNull Collection<ValueParameterDescriptor> constructorParameters,
428                @NotNull ClassDescriptor classDescriptor,
429                @NotNull BindingTrace trace
430        ) {
431            JetType returnType = classDescriptor.getDefaultType();
432    
433            SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
434                    classDescriptor,
435                    Annotations.EMPTY,
436                    COPY_METHOD_NAME,
437                    CallableMemberDescriptor.Kind.SYNTHESIZED,
438                    classDescriptor.getSource()
439            );
440    
441            List<ValueParameterDescriptor> parameterDescriptors = Lists.newArrayList();
442    
443            for (ValueParameterDescriptor parameter : constructorParameters) {
444                PropertyDescriptor propertyDescriptor = trace.getBindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
445                // If parameter hasn't corresponding property, so it mustn't have default value as a parameter in copy function for data class
446                boolean declaresDefaultValue = propertyDescriptor != null;
447                ValueParameterDescriptorImpl parameterDescriptor =
448                        new ValueParameterDescriptorImpl(functionDescriptor, null, parameter.getIndex(), parameter.getAnnotations(),
449                                                         parameter.getName(), parameter.getType(),
450                                                         declaresDefaultValue,
451                                                         parameter.getVarargElementType(), SourceElement.NO_SOURCE);
452                parameterDescriptors.add(parameterDescriptor);
453                if (declaresDefaultValue) {
454                    trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameterDescriptor, propertyDescriptor);
455                }
456            }
457    
458            functionDescriptor.initialize(
459                    null,
460                    classDescriptor.getThisAsReceiverParameter(),
461                    Collections.<TypeParameterDescriptor>emptyList(),
462                    parameterDescriptors,
463                    returnType,
464                    Modality.FINAL,
465                    Visibilities.PUBLIC // TODO: test
466            );
467    
468            trace.record(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor, functionDescriptor);
469            return functionDescriptor;
470        }
471    
472        public static Visibility getDefaultVisibility(JetModifierListOwner modifierListOwner, DeclarationDescriptor containingDescriptor) {
473            Visibility defaultVisibility;
474            if (containingDescriptor instanceof ClassDescriptor) {
475                JetModifierList modifierList = modifierListOwner.getModifierList();
476                defaultVisibility = modifierList != null && modifierList.hasModifier(OVERRIDE_KEYWORD)
477                                               ? Visibilities.INHERITED
478                                               : Visibilities.INTERNAL;
479            }
480            else if (containingDescriptor instanceof FunctionDescriptor) {
481                defaultVisibility = Visibilities.LOCAL;
482            }
483            else {
484                defaultVisibility = Visibilities.INTERNAL;
485            }
486            return defaultVisibility;
487        }
488    
489        public static Modality getDefaultModality(DeclarationDescriptor containingDescriptor, boolean isBodyPresent) {
490            Modality defaultModality;
491            if (containingDescriptor instanceof ClassDescriptor) {
492                boolean isTrait = ((ClassDescriptor) containingDescriptor).getKind() == ClassKind.TRAIT;
493                boolean isDefinitelyAbstract = isTrait && !isBodyPresent;
494                Modality basicModality = isTrait ? Modality.OPEN : Modality.FINAL;
495                defaultModality = isDefinitelyAbstract ? Modality.ABSTRACT : basicModality;
496            }
497            else {
498                defaultModality = Modality.FINAL;
499            }
500            return defaultModality;
501        }
502    
503        @NotNull
504        private List<ValueParameterDescriptor> resolveValueParameters(
505                FunctionDescriptor functionDescriptor,
506                WritableScope parameterScope,
507                List<JetParameter> valueParameters,
508                BindingTrace trace
509        ) {
510            List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
511            for (int i = 0; i < valueParameters.size(); i++) {
512                JetParameter valueParameter = valueParameters.get(i);
513                JetTypeReference typeReference = valueParameter.getTypeReference();
514    
515                JetType type;
516                if (typeReference == null) {
517                    trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter));
518                    type = ErrorUtils.createErrorType("Type annotation was missing");
519                }
520                else {
521                    type = typeResolver.resolveType(parameterScope, typeReference, trace, true);
522                }
523    
524                if (!(functionDescriptor instanceof ConstructorDescriptor)) {
525                    checkParameterHasNoValOrVar(trace, valueParameter, VAL_OR_VAR_ON_FUN_PARAMETER);
526                    checkParameterHasNoModifier(trace, valueParameter);
527                } else {
528                    checkConstructorParameterHasNoModifier(trace, valueParameter);
529                }
530    
531                ValueParameterDescriptor valueParameterDescriptor =
532                        resolveValueParameterDescriptor(parameterScope, functionDescriptor, valueParameter, i, type, trace);
533                parameterScope.addVariableDescriptor(valueParameterDescriptor);
534                result.add(valueParameterDescriptor);
535            }
536            return result;
537        }
538    
539        @NotNull
540        public ValueParameterDescriptorImpl resolveValueParameterDescriptor(
541                JetScope scope, DeclarationDescriptor declarationDescriptor,
542                JetParameter valueParameter, int index, JetType type, BindingTrace trace
543        ) {
544            return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
545                    annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace));
546        }
547    
548        @NotNull
549        public ValueParameterDescriptorImpl resolveValueParameterDescriptorWithAnnotationArguments(
550                JetScope scope, DeclarationDescriptor declarationDescriptor,
551                JetParameter valueParameter, int index, JetType type, BindingTrace trace
552        ) {
553            return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
554                    annotationResolver.resolveAnnotationsWithArguments(scope, valueParameter.getModifierList(), trace));
555        }
556    
557        @NotNull
558        private ValueParameterDescriptorImpl resolveValueParameterDescriptor(
559                DeclarationDescriptor declarationDescriptor,
560                JetParameter valueParameter, int index, JetType type, BindingTrace trace,
561                Annotations annotations
562        ) {
563            JetType varargElementType = null;
564            JetType variableType = type;
565            if (valueParameter.hasModifier(VARARG_KEYWORD)) {
566                varargElementType = type;
567                variableType = getVarargParameterType(type);
568            }
569            ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
570                    declarationDescriptor,
571                    null,
572                    index,
573                    annotations,
574                    JetPsiUtil.safeName(valueParameter.getName()),
575                    variableType,
576                    valueParameter.hasDefaultValue(),
577                    varargElementType,
578                    toSourceElement(valueParameter)
579            );
580    
581            trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
582            return valueParameterDescriptor;
583        }
584    
585        @NotNull
586        private JetType getVarargParameterType(@NotNull JetType elementType) {
587            JetType primitiveArrayType = builtIns.getPrimitiveArrayJetTypeByPrimitiveJetType(elementType);
588            if (primitiveArrayType != null) {
589                return primitiveArrayType;
590            }
591            return builtIns.getArrayType(Variance.OUT_VARIANCE, elementType);
592        }
593    
594        public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor(
595                DeclarationDescriptor containingDescriptor,
596                WritableScope extensibleScope,
597                List<JetTypeParameter> typeParameters,
598                BindingTrace trace
599        ) {
600            List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
601            for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
602                JetTypeParameter typeParameter = typeParameters.get(i);
603                result.add(resolveTypeParameterForCallableDescriptor(containingDescriptor, extensibleScope, typeParameter, i, trace));
604            }
605            return result;
606        }
607    
608        private TypeParameterDescriptorImpl resolveTypeParameterForCallableDescriptor(
609                DeclarationDescriptor containingDescriptor,
610                WritableScope extensibleScope,
611                JetTypeParameter typeParameter,
612                int index,
613                BindingTrace trace
614        ) {
615            if (typeParameter.getVariance() != Variance.INVARIANT) {
616                assert !(containingDescriptor instanceof ClassifierDescriptor) : "This method is intended for functions/properties";
617                trace.report(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY.on(typeParameter));
618            }
619    
620            // TODO: Support annotation for type parameters
621            AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, trace);
622    
623            TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
624                    containingDescriptor,
625                    Annotations.EMPTY,
626                    typeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
627                    typeParameter.getVariance(),
628                    JetPsiUtil.safeName(typeParameter.getName()),
629                    index,
630                    toSourceElement(typeParameter)
631            );
632            trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
633            extensibleScope.addTypeParameterDescriptor(typeParameterDescriptor);
634            return typeParameterDescriptor;
635        }
636    
637        @NotNull
638        public static ConstructorDescriptorImpl createAndRecordPrimaryConstructorForObject(
639                @Nullable JetClassOrObject object,
640                @NotNull ClassDescriptor classDescriptor,
641                @NotNull BindingTrace trace
642        ) {
643            ConstructorDescriptorImpl constructorDescriptor =
644                    DescriptorFactory.createPrimaryConstructorForObject(classDescriptor, toSourceElement(object));
645            if (object != null) {
646                trace.record(CONSTRUCTOR, object, constructorDescriptor);
647            }
648            return constructorDescriptor;
649        }
650    
651        static final class UpperBoundCheckerTask {
652            JetTypeReference upperBound;
653            JetType upperBoundType;
654            boolean isClassObjectConstraint;
655    
656            private UpperBoundCheckerTask(JetTypeReference upperBound, JetType upperBoundType, boolean classObjectConstraint) {
657                this.upperBound = upperBound;
658                this.upperBoundType = upperBoundType;
659                isClassObjectConstraint = classObjectConstraint;
660            }
661        }
662    
663        public void resolveGenericBounds(
664                @NotNull JetTypeParameterListOwner declaration,
665                @NotNull DeclarationDescriptor descriptor,
666                JetScope scope,
667                List<TypeParameterDescriptorImpl> parameters,
668                BindingTrace trace
669        ) {
670            List<UpperBoundCheckerTask> deferredUpperBoundCheckerTasks = Lists.newArrayList();
671    
672            List<JetTypeParameter> typeParameters = declaration.getTypeParameters();
673            Map<Name, TypeParameterDescriptorImpl> parameterByName = Maps.newHashMap();
674            for (int i = 0; i < typeParameters.size(); i++) {
675                JetTypeParameter jetTypeParameter = typeParameters.get(i);
676                TypeParameterDescriptorImpl typeParameterDescriptor = parameters.get(i);
677    
678                parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
679    
680                JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
681                if (extendsBound != null) {
682                    JetType type = typeResolver.resolveType(scope, extendsBound, trace, false);
683                    typeParameterDescriptor.addUpperBound(type);
684                    deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(extendsBound, type, false));
685                }
686            }
687            for (JetTypeConstraint constraint : declaration.getTypeConstraints()) {
688                reportUnsupportedClassObjectConstraint(trace, constraint);
689    
690                JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName();
691                if (subjectTypeParameterName == null) {
692                    continue;
693                }
694                Name referencedName = subjectTypeParameterName.getReferencedNameAsName();
695                TypeParameterDescriptorImpl typeParameterDescriptor = parameterByName.get(referencedName);
696                JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
697                JetType bound = null;
698                if (boundTypeReference != null) {
699                    bound = typeResolver.resolveType(scope, boundTypeReference, trace, false);
700                    deferredUpperBoundCheckerTasks
701                            .add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectConstraint()));
702                }
703    
704                if (typeParameterDescriptor != null) {
705                    trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
706                    if (bound != null) {
707                        if (constraint.isClassObjectConstraint()) {
708                            // Class object bounds are not supported
709                            //typeParameterDescriptor.addClassObjectBound(bound);
710                        }
711                        else {
712                            typeParameterDescriptor.addUpperBound(bound);
713                        }
714                    }
715                }
716            }
717    
718            for (TypeParameterDescriptorImpl parameter : parameters) {
719                parameter.addDefaultUpperBound();
720    
721                parameter.setInitialized();
722    
723                checkConflictingUpperBounds(trace, parameter, typeParameters.get(parameter.getIndex()));
724            }
725    
726            if (!(declaration instanceof JetClass)) {
727                for (UpperBoundCheckerTask checkerTask : deferredUpperBoundCheckerTasks) {
728                    checkUpperBoundType(checkerTask.upperBound, checkerTask.upperBoundType, checkerTask.isClassObjectConstraint, trace);
729                }
730    
731                checkNamesInConstraints(declaration, descriptor, scope, trace);
732            }
733        }
734    
735        public static void checkConflictingUpperBounds(
736                @NotNull BindingTrace trace,
737                @NotNull TypeParameterDescriptor parameter,
738                @NotNull JetTypeParameter typeParameter
739        ) {
740            if (KotlinBuiltIns.isNothing(parameter.getUpperBoundsAsType())) {
741                trace.report(CONFLICTING_UPPER_BOUNDS.on(typeParameter, parameter));
742            }
743    
744            JetType classObjectType = parameter.getClassObjectType();
745            if (classObjectType != null && KotlinBuiltIns.isNothing(classObjectType)) {
746                trace.report(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS.on(typeParameter, parameter));
747            }
748        }
749    
750        public void checkNamesInConstraints(
751                @NotNull JetTypeParameterListOwner declaration,
752                @NotNull DeclarationDescriptor descriptor,
753                @NotNull JetScope scope,
754                @NotNull BindingTrace trace
755        ) {
756            for (JetTypeConstraint constraint : declaration.getTypeConstraints()) {
757                JetSimpleNameExpression nameExpression = constraint.getSubjectTypeParameterName();
758                if (nameExpression == null) continue;
759    
760                Name name = nameExpression.getReferencedNameAsName();
761    
762                ClassifierDescriptor classifier = scope.getClassifier(name);
763                if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == descriptor) continue;
764    
765                if (classifier != null) {
766                    // To tell the user that we look only for locally defined type parameters
767                    trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(nameExpression, constraint, declaration));
768                    trace.record(BindingContext.REFERENCE_TARGET, nameExpression, classifier);
769                }
770                else {
771                    trace.report(UNRESOLVED_REFERENCE.on(nameExpression, nameExpression));
772                }
773    
774                JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
775                if (boundTypeReference != null) {
776                    typeResolver.resolveType(scope, boundTypeReference, trace, true);
777                }
778            }
779        }
780    
781        public static void reportUnsupportedClassObjectConstraint(BindingTrace trace, JetTypeConstraint constraint) {
782            if (constraint.isClassObjectConstraint()) {
783                trace.report(UNSUPPORTED.on(constraint, "Class objects constraints are not supported yet"));
784            }
785        }
786    
787        public static void checkUpperBoundType(
788                JetTypeReference upperBound,
789                @NotNull JetType upperBoundType,
790                boolean isClassObjectConstraint,
791                BindingTrace trace
792        ) {
793            if (!TypeUtils.canHaveSubtypes(JetTypeChecker.DEFAULT, upperBoundType)) {
794                if (isClassObjectConstraint) {
795                    trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, upperBoundType));
796                }
797                else {
798                    trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
799                }
800            }
801            if (TypesPackage.isDynamic(upperBoundType)) {
802                trace.report(DYNAMIC_UPPER_BOUND.on(upperBound));
803            }
804        }
805    
806        @NotNull
807        public VariableDescriptor resolveLocalVariableDescriptor(
808                @NotNull JetScope scope,
809                @NotNull JetParameter parameter,
810                BindingTrace trace
811        ) {
812            JetType type = resolveParameterType(scope, parameter, trace);
813            return resolveLocalVariableDescriptor(parameter, type, trace, scope);
814        }
815    
816        private JetType resolveParameterType(JetScope scope, JetParameter parameter, BindingTrace trace) {
817            JetTypeReference typeReference = parameter.getTypeReference();
818            JetType type;
819            if (typeReference != null) {
820                type = typeResolver.resolveType(scope, typeReference, trace, true);
821            }
822            else {
823                // Error is reported by the parser
824                type = ErrorUtils.createErrorType("Annotation is absent");
825            }
826            if (parameter.hasModifier(VARARG_KEYWORD)) {
827                return getVarargParameterType(type);
828            }
829            return type;
830        }
831    
832        public VariableDescriptor resolveLocalVariableDescriptor(
833                @NotNull JetParameter parameter,
834                @NotNull JetType type,
835                BindingTrace trace,
836                @NotNull JetScope scope
837        ) {
838            VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
839                    scope.getContainingDeclaration(),
840                    annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
841                    JetPsiUtil.safeName(parameter.getName()),
842                    type,
843                    false,
844                    toSourceElement(parameter)
845            );
846            trace.record(BindingContext.VALUE_PARAMETER, parameter, variableDescriptor);
847            return variableDescriptor;
848        }
849    
850        @NotNull
851        public VariableDescriptor resolveLocalVariableDescriptor(
852                JetScope scope,
853                JetVariableDeclaration variable,
854                DataFlowInfo dataFlowInfo,
855                BindingTrace trace
856        ) {
857            DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration();
858            // SCRIPT: Create property descriptors
859            if (JetPsiUtil.isScriptDeclaration(variable)) {
860                PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
861                        containingDeclaration,
862                        annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
863                        Modality.FINAL,
864                        Visibilities.INTERNAL,
865                        variable.isVar(),
866                        JetPsiUtil.safeName(variable.getName()),
867                        CallableMemberDescriptor.Kind.DECLARATION,
868                        toSourceElement(variable)
869                );
870    
871                JetType type =
872                        getVariableType(propertyDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
873    
874                ReceiverParameterDescriptor receiverParameter = ((ScriptDescriptor) containingDeclaration).getThisAsReceiverParameter();
875                propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), receiverParameter, (JetType) null);
876                initializeWithDefaultGetterSetter(propertyDescriptor);
877                trace.record(BindingContext.VARIABLE, variable, propertyDescriptor);
878                return propertyDescriptor;
879            }
880            else {
881                VariableDescriptorImpl variableDescriptor =
882                        resolveLocalVariableDescriptorWithType(scope, variable, null, trace);
883    
884                JetType type =
885                        getVariableType(variableDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
886                variableDescriptor.setOutType(type);
887                return variableDescriptor;
888            }
889        }
890    
891        private static void initializeWithDefaultGetterSetter(PropertyDescriptorImpl propertyDescriptor) {
892            PropertyGetterDescriptorImpl getter = propertyDescriptor.getGetter();
893            if (getter == null && !Visibilities.isPrivate(propertyDescriptor.getVisibility())) {
894                getter = DescriptorFactory.createDefaultGetter(propertyDescriptor);
895                getter.initialize(propertyDescriptor.getType());
896            }
897    
898            PropertySetterDescriptor setter = propertyDescriptor.getSetter();
899            if (setter == null && propertyDescriptor.isVar()) {
900                setter = DescriptorFactory.createDefaultSetter(propertyDescriptor);
901            }
902            propertyDescriptor.initialize(getter, setter);
903        }
904    
905        @NotNull
906        public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(
907                @NotNull JetScope scope,
908                @NotNull JetVariableDeclaration variable,
909                @Nullable JetType type,
910                @NotNull BindingTrace trace
911        ) {
912            VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
913                    scope.getContainingDeclaration(),
914                    annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
915                    JetPsiUtil.safeName(variable.getName()),
916                    type,
917                    variable.isVar(),
918                    toSourceElement(variable)
919            );
920            trace.record(BindingContext.VARIABLE, variable, variableDescriptor);
921            return variableDescriptor;
922        }
923    
924        @NotNull
925        public PropertyDescriptor resolvePropertyDescriptor(
926                @NotNull DeclarationDescriptor containingDeclaration,
927                @NotNull JetScope scope,
928                @NotNull JetProperty property,
929                @NotNull BindingTrace trace,
930                @NotNull DataFlowInfo dataFlowInfo
931        ) {
932            JetModifierList modifierList = property.getModifierList();
933            boolean isVar = property.isVar();
934    
935            boolean hasBody = hasBody(property);
936            Modality modality = containingDeclaration instanceof ClassDescriptor
937                                ? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, hasBody))
938                                : Modality.FINAL;
939            Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
940            PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
941                    containingDeclaration,
942                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
943                    modality,
944                    visibility,
945                    isVar,
946                    JetPsiUtil.safeName(property.getName()),
947                    CallableMemberDescriptor.Kind.DECLARATION,
948                    toSourceElement(property)
949            );
950    
951            List<TypeParameterDescriptorImpl> typeParameterDescriptors;
952            JetScope scopeWithTypeParameters;
953            JetType receiverType = null;
954    
955            {
956                List<JetTypeParameter> typeParameters = property.getTypeParameters();
957                if (typeParameters.isEmpty()) {
958                    scopeWithTypeParameters = scope;
959                    typeParameterDescriptors = Collections.emptyList();
960                }
961                else {
962                    WritableScope writableScope = new WritableScopeImpl(
963                            scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace),
964                            "Scope with type parameters of a property");
965                    typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(propertyDescriptor, writableScope, typeParameters,
966                                                                                          trace);
967                    writableScope.changeLockLevel(WritableScope.LockLevel.READING);
968                    resolveGenericBounds(property, propertyDescriptor, writableScope, typeParameterDescriptors, trace);
969                    scopeWithTypeParameters = writableScope;
970                }
971    
972                JetTypeReference receiverTypeRef = property.getReceiverTypeReference();
973                if (receiverTypeRef != null) {
974                    receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef, trace, true);
975                }
976            }
977    
978            ReceiverParameterDescriptor receiverDescriptor =
979                    DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
980    
981            ReceiverParameterDescriptor implicitInitializerReceiver = property.hasDelegate() ? NO_RECEIVER_PARAMETER : receiverDescriptor;
982    
983            JetScope propertyScope = JetScopeUtils.getPropertyDeclarationInnerScope(propertyDescriptor, scope, typeParameterDescriptors,
984                                                                                    implicitInitializerReceiver, trace);
985    
986            JetType type = getVariableType(propertyDescriptor, propertyScope, property, dataFlowInfo, true, trace);
987    
988            propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
989                                       receiverDescriptor);
990    
991            PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
992            PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
993    
994            propertyDescriptor.initialize(getter, setter);
995    
996            trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
997            return propertyDescriptor;
998        }
999    
1000        /*package*/
1001        static boolean hasBody(JetProperty property) {
1002            boolean hasBody = property.hasDelegateExpressionOrInitializer();
1003            if (!hasBody) {
1004                JetPropertyAccessor getter = property.getGetter();
1005                if (getter != null && getter.hasBody()) {
1006                    hasBody = true;
1007                }
1008                JetPropertyAccessor setter = property.getSetter();
1009                if (!hasBody && setter != null && setter.hasBody()) {
1010                    hasBody = true;
1011                }
1012            }
1013            return hasBody;
1014        }
1015    
1016        @NotNull
1017        private JetType getVariableType(
1018                @NotNull final VariableDescriptorImpl variableDescriptor,
1019                @NotNull final JetScope scope,
1020                @NotNull final JetVariableDeclaration variable,
1021                @NotNull final DataFlowInfo dataFlowInfo,
1022                boolean notLocal,
1023                @NotNull final BindingTrace trace
1024        ) {
1025            JetTypeReference propertyTypeRef = variable.getTypeReference();
1026    
1027            boolean hasDelegate = variable instanceof JetProperty && ((JetProperty) variable).hasDelegateExpression();
1028            if (propertyTypeRef == null) {
1029                if (!variable.hasInitializer()) {
1030                    if (hasDelegate && variableDescriptor instanceof PropertyDescriptor) {
1031                        final JetProperty property = (JetProperty) variable;
1032                        if (property.hasDelegateExpression()) {
1033                            return DeferredType.createRecursionIntolerant(
1034                                    storageManager,
1035                                    trace,
1036                                    new Function0<JetType>() {
1037                                        @Override
1038                                        public JetType invoke() {
1039                                            return resolveDelegatedPropertyType(property, (PropertyDescriptor) variableDescriptor, scope,
1040                                                                                property.getDelegateExpression(), dataFlowInfo, trace);
1041                                        }
1042                                    });
1043                        }
1044                    }
1045                    if (!notLocal) {
1046                        trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable));
1047                    }
1048                    return ErrorUtils.createErrorType("No type, no body");
1049                }
1050                else {
1051                    if (notLocal) {
1052                        return DeferredType.createRecursionIntolerant(
1053                                storageManager,
1054                                trace,
1055                                new Function0<JetType>() {
1056                                    @Override
1057                                    public JetType invoke() {
1058                                        JetType initializerType = resolveInitializerType(scope, variable.getInitializer(), dataFlowInfo, trace);
1059                                        setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, initializerType, trace);
1060                                        return transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace);
1061                                    }
1062                                }
1063                        );
1064                    }
1065                    else {
1066                        JetType initializerType = resolveInitializerType(scope, variable.getInitializer(), dataFlowInfo, trace);
1067                        setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, initializerType, trace);
1068                        return initializerType;
1069                    }
1070                }
1071            }
1072            else {
1073                JetType type = typeResolver.resolveType(scope, propertyTypeRef, trace, true);
1074                setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, type, trace);
1075                return type;
1076            }
1077        }
1078    
1079        private void setConstantForVariableIfNeeded(
1080                @NotNull VariableDescriptorImpl variableDescriptor,
1081                @NotNull final JetScope scope,
1082                @NotNull final JetVariableDeclaration variable,
1083                @NotNull final DataFlowInfo dataFlowInfo,
1084                @NotNull final JetType variableType,
1085                @NotNull final BindingTrace trace
1086        ) {
1087            if (!shouldRecordInitializerForProperty(variableDescriptor, variableType)) return;
1088    
1089            if (!variable.hasInitializer()) return;
1090    
1091            variableDescriptor.setCompileTimeInitializer(
1092                storageManager.createRecursionTolerantNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
1093                    @Nullable
1094                    @Override
1095                    public CompileTimeConstant<?> invoke() {
1096                        JetExpression initializer = variable.getInitializer();
1097                        JetType initializerType = expressionTypingServices.safeGetType(scope, initializer, variableType, dataFlowInfo, trace);
1098                        CompileTimeConstant<?> constant = ConstantExpressionEvaluator.OBJECT$.evaluate(initializer, trace, initializerType);
1099                        if (constant instanceof IntegerValueTypeConstant) {
1100                            return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) constant, initializerType);
1101                        }
1102                        return constant;
1103                    }
1104                }, null)
1105            );
1106        }
1107    
1108        @NotNull
1109        private JetType resolveDelegatedPropertyType(
1110                @NotNull JetProperty property,
1111                @NotNull PropertyDescriptor propertyDescriptor,
1112                @NotNull JetScope scope,
1113                @NotNull JetExpression delegateExpression,
1114                @NotNull DataFlowInfo dataFlowInfo,
1115                @NotNull BindingTrace trace
1116        ) {
1117            JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, scope, trace);
1118    
1119            JetType type = delegatedPropertyResolver.resolveDelegateExpression(
1120                    delegateExpression, property, propertyDescriptor, scope, accessorScope, trace, dataFlowInfo);
1121    
1122            if (type != null) {
1123                JetType getterReturnType = delegatedPropertyResolver
1124                        .getDelegatedPropertyGetMethodReturnType(propertyDescriptor, delegateExpression, type, trace, accessorScope);
1125                if (getterReturnType != null) {
1126                    return getterReturnType;
1127                }
1128            }
1129            return ErrorUtils.createErrorType("Type from delegate");
1130        }
1131    
1132        @Nullable
1133        private static JetType transformAnonymousTypeIfNeeded(
1134                @NotNull DeclarationDescriptorWithVisibility descriptor,
1135                @NotNull JetNamedDeclaration declaration,
1136                @NotNull JetType type,
1137                @NotNull BindingTrace trace
1138        ) {
1139            ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
1140            if (classifierDescriptor == null || !DescriptorUtils.isAnonymousObject(classifierDescriptor)) {
1141                return type;
1142            }
1143    
1144            boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null;
1145            boolean isLocal = DescriptorUtils.isLocal(descriptor);
1146            Visibility visibility = descriptor.getVisibility();
1147            boolean transformNeeded = !isLocal && !visibility.isPublicAPI()
1148                                      && !(definedInClass && Visibilities.isPrivate(visibility));
1149            if (transformNeeded) {
1150                if (type.getConstructor().getSupertypes().size() == 1) {
1151                    assert type.getArguments().isEmpty() : "Object expression couldn't have any type parameters!";
1152                    return type.getConstructor().getSupertypes().iterator().next();
1153                }
1154                else {
1155                    trace.report(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED.on(declaration, type.getConstructor().getSupertypes()));
1156                }
1157            }
1158            return type;
1159        }
1160    
1161        @NotNull
1162        private JetType resolveInitializerType(
1163                @NotNull JetScope scope,
1164                @NotNull JetExpression initializer,
1165                @NotNull DataFlowInfo dataFlowInfo,
1166                @NotNull BindingTrace trace
1167        ) {
1168            return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
1169        }
1170    
1171        @Nullable
1172        private PropertySetterDescriptor resolvePropertySetterDescriptor(
1173                @NotNull JetScope scope,
1174                @NotNull JetProperty property,
1175                @NotNull PropertyDescriptor propertyDescriptor,
1176                BindingTrace trace
1177        ) {
1178            JetPropertyAccessor setter = property.getSetter();
1179            PropertySetterDescriptorImpl setterDescriptor = null;
1180            if (setter != null) {
1181                Annotations annotations =
1182                        annotationResolver.resolveAnnotationsWithoutArguments(scope, setter.getModifierList(), trace);
1183                JetParameter parameter = setter.getParameter();
1184    
1185                setterDescriptor = new PropertySetterDescriptorImpl(propertyDescriptor, annotations,
1186                                                                    resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
1187                                                                    resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
1188                                                                    setter.hasBody(), false,
1189                                                                    CallableMemberDescriptor.Kind.DECLARATION, null, toSourceElement(setter));
1190                if (parameter != null) {
1191    
1192                    // This check is redundant: the parser does not allow a default value, but we'll keep it just in case
1193                    if (parameter.hasDefaultValue()) {
1194                        trace.report(SETTER_PARAMETER_WITH_DEFAULT_VALUE.on(parameter.getDefaultValue()));
1195                    }
1196    
1197                    JetType type;
1198                    JetTypeReference typeReference = parameter.getTypeReference();
1199                    if (typeReference == null) {
1200                        type = propertyDescriptor.getType(); // TODO : this maybe unknown at this point
1201                    }
1202                    else {
1203                        type = typeResolver.resolveType(scope, typeReference, trace, true);
1204                        JetType inType = propertyDescriptor.getType();
1205                        if (inType != null) {
1206                            if (!TypeUtils.equalTypes(type, inType)) {
1207                                trace.report(WRONG_SETTER_PARAMETER_TYPE.on(typeReference, inType, type));
1208                            }
1209                        }
1210                        else {
1211                            // TODO : the same check may be needed later???
1212                        }
1213                    }
1214    
1215                    ValueParameterDescriptorImpl valueParameterDescriptor =
1216                            resolveValueParameterDescriptor(scope, setterDescriptor, parameter, 0, type, trace);
1217                    setterDescriptor.initialize(valueParameterDescriptor);
1218                }
1219                else {
1220                    setterDescriptor.initializeDefault();
1221                }
1222    
1223                trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
1224            }
1225            else if (property.isVar()) {
1226                setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, !property.hasDelegate());
1227            }
1228    
1229            if (!property.isVar()) {
1230                if (setter != null) {
1231                    //                trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
1232                    trace.report(VAL_WITH_SETTER.on(setter));
1233                }
1234            }
1235            return setterDescriptor;
1236        }
1237    
1238        @Nullable
1239        private PropertyGetterDescriptorImpl resolvePropertyGetterDescriptor(
1240                @NotNull JetScope scope,
1241                @NotNull JetProperty property,
1242                @NotNull PropertyDescriptor propertyDescriptor,
1243                BindingTrace trace
1244        ) {
1245            PropertyGetterDescriptorImpl getterDescriptor;
1246            JetPropertyAccessor getter = property.getGetter();
1247            if (getter != null) {
1248                Annotations annotations =
1249                        annotationResolver.resolveAnnotationsWithoutArguments(scope, getter.getModifierList(), trace);
1250    
1251                JetType outType = propertyDescriptor.getType();
1252                JetType returnType = outType;
1253                JetTypeReference returnTypeReference = getter.getReturnTypeReference();
1254                if (returnTypeReference != null) {
1255                    returnType = typeResolver.resolveType(scope, returnTypeReference, trace, true);
1256                    if (outType != null && !TypeUtils.equalTypes(returnType, outType)) {
1257                        trace.report(WRONG_GETTER_RETURN_TYPE.on(returnTypeReference, propertyDescriptor.getReturnType(), outType));
1258                    }
1259                }
1260    
1261                getterDescriptor = new PropertyGetterDescriptorImpl(propertyDescriptor, annotations,
1262                                                                    resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
1263                                                                    resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
1264                                                                    getter.hasBody(), false,
1265                                                                    CallableMemberDescriptor.Kind.DECLARATION, null, toSourceElement(getter));
1266                getterDescriptor.initialize(returnType);
1267                trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
1268            }
1269            else {
1270                getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, !property.hasDelegate());
1271                getterDescriptor.initialize(propertyDescriptor.getType());
1272            }
1273            return getterDescriptor;
1274        }
1275    
1276        @NotNull
1277        private ConstructorDescriptorImpl createConstructorDescriptor(
1278                @NotNull JetScope scope,
1279                @NotNull ClassDescriptor classDescriptor,
1280                boolean isPrimary,
1281                @Nullable JetModifierList modifierList,
1282                @NotNull JetDeclaration declarationToTrace,
1283                List<TypeParameterDescriptor> typeParameters, @NotNull List<JetParameter> valueParameters, BindingTrace trace
1284        ) {
1285            ConstructorDescriptorImpl constructorDescriptor = ConstructorDescriptorImpl.create(
1286                    classDescriptor,
1287                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
1288                    isPrimary,
1289                    toSourceElement(declarationToTrace)
1290            );
1291            trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor);
1292            WritableScopeImpl parameterScope = new WritableScopeImpl(
1293                    scope, constructorDescriptor, new TraceBasedRedeclarationHandler(trace), "Scope with value parameters of a constructor");
1294            parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
1295            ConstructorDescriptorImpl constructor = constructorDescriptor.initialize(
1296                    typeParameters,
1297                    resolveValueParameters(constructorDescriptor, parameterScope, valueParameters, trace),
1298                    resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor))
1299            );
1300            if (isAnnotationClass(classDescriptor)) {
1301                CompileTimeConstantUtils.checkConstructorParametersType(valueParameters, trace);
1302            }
1303            return constructor;
1304        }
1305    
1306        @Nullable
1307        public ConstructorDescriptorImpl resolvePrimaryConstructorDescriptor(
1308                @NotNull JetScope scope,
1309                @NotNull ClassDescriptor classDescriptor,
1310                @NotNull JetClass classElement,
1311                BindingTrace trace
1312        ) {
1313            if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) return null;
1314            return createConstructorDescriptor(
1315                    scope,
1316                    classDescriptor,
1317                    true,
1318                    classElement.getPrimaryConstructorModifierList(),
1319                    classElement,
1320                    classDescriptor.getTypeConstructor().getParameters(), classElement.getPrimaryConstructorParameters(), trace);
1321        }
1322    
1323        @NotNull
1324        public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
1325                @NotNull ClassDescriptor classDescriptor,
1326                @NotNull ValueParameterDescriptor valueParameter,
1327                @NotNull JetScope scope,
1328                @NotNull JetParameter parameter, BindingTrace trace
1329        ) {
1330            JetType type = resolveParameterType(scope, parameter, trace);
1331            Name name = parameter.getNameAsSafeName();
1332            boolean isMutable = parameter.isMutable();
1333            JetModifierList modifierList = parameter.getModifierList();
1334    
1335            if (modifierList != null) {
1336                if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
1337                    trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(parameter));
1338                }
1339            }
1340    
1341            PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
1342                    classDescriptor,
1343                    valueParameter.getAnnotations(),
1344                    resolveModalityFromModifiers(parameter, Modality.FINAL),
1345                    resolveVisibilityFromModifiers(parameter, getDefaultVisibility(parameter, classDescriptor)),
1346                    isMutable,
1347                    name,
1348                    CallableMemberDescriptor.Kind.DECLARATION,
1349                    toSourceElement(parameter)
1350            );
1351            propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
1352                                       getDispatchReceiverParameterIfNeeded(classDescriptor), NO_RECEIVER_PARAMETER);
1353    
1354            PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor);
1355            PropertySetterDescriptor setter =
1356                    propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor) : null;
1357    
1358            propertyDescriptor.initialize(getter, setter);
1359            getter.initialize(propertyDescriptor.getType());
1360    
1361            trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
1362            trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
1363            return propertyDescriptor;
1364        }
1365    
1366        public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, @NotNull BindingTrace trace) {
1367            if (type.isError()) return;
1368    
1369            JetTypeElement typeElement = typeReference.getTypeElement();
1370            if (typeElement == null) return;
1371    
1372            List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
1373            List<TypeProjection> arguments = type.getArguments();
1374            assert parameters.size() == arguments.size();
1375    
1376            List<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
1377    
1378            // A type reference from Kotlin code can yield a flexible type only if it's `ft<T1, T2>`, whose bounds should not be checked
1379            if (TypesPackage.isFlexible(type) && !TypesPackage.isDynamic(type)) {
1380                assert jetTypeArguments.size() == 2
1381                        : "Flexible type cannot be denoted in Kotlin otherwise than as ft<T1, T2>, but was: "
1382                          + JetPsiUtil.getElementTextWithContext(typeReference);
1383                // it's really ft<Foo, Bar>
1384                Flexibility flexibility = TypesPackage.flexibility(type);
1385                checkBounds(jetTypeArguments.get(0), flexibility.getLowerBound(), trace);
1386                checkBounds(jetTypeArguments.get(1), flexibility.getUpperBound(), trace);
1387                return;
1388            }
1389    
1390            assert jetTypeArguments.size() == arguments.size() : typeElement.getText() + ": " + jetTypeArguments + " - " + arguments;
1391    
1392            TypeSubstitutor substitutor = TypeSubstitutor.create(type);
1393            for (int i = 0; i < jetTypeArguments.size(); i++) {
1394                JetTypeReference jetTypeArgument = jetTypeArguments.get(i);
1395    
1396                if (jetTypeArgument == null) continue;
1397    
1398                JetType typeArgument = arguments.get(i).getType();
1399                checkBounds(jetTypeArgument, typeArgument, trace);
1400    
1401                TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
1402                checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace);
1403            }
1404        }
1405    
1406        public static void checkBounds(
1407                @NotNull JetTypeReference jetTypeArgument,
1408                @NotNull JetType typeArgument,
1409                @NotNull TypeParameterDescriptor typeParameterDescriptor,
1410                @NotNull TypeSubstitutor substitutor,
1411                @NotNull BindingTrace trace
1412        ) {
1413            for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
1414                JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
1415                if (!JetTypeChecker.DEFAULT.isSubtypeOf(typeArgument, substitutedBound)) {
1416                    trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument));
1417                }
1418            }
1419        }
1420    
1421        public static boolean checkHasOuterClassInstance(
1422                @NotNull JetScope scope,
1423                @NotNull BindingTrace trace,
1424                @NotNull PsiElement reportErrorsOn,
1425                @NotNull ClassDescriptor target
1426        ) {
1427            ClassDescriptor classDescriptor = getContainingClass(scope);
1428    
1429            if (!isInsideOuterClassOrItsSubclass(classDescriptor, target)) {
1430                return true;
1431            }
1432    
1433            while (classDescriptor != null) {
1434                if (isSubclass(classDescriptor, target)) {
1435                    return true;
1436                }
1437    
1438                if (isStaticNestedClass(classDescriptor)) {
1439                    trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
1440                    return false;
1441                }
1442                classDescriptor = getParentOfType(classDescriptor, ClassDescriptor.class, true);
1443            }
1444            return true;
1445        }
1446    
1447        private static boolean isInsideOuterClassOrItsSubclass(@Nullable DeclarationDescriptor nested, @NotNull ClassDescriptor outer) {
1448            if (nested == null) return false;
1449    
1450            if (nested instanceof ClassDescriptor && isSubclass((ClassDescriptor) nested, outer)) return true;
1451    
1452            return isInsideOuterClassOrItsSubclass(nested.getContainingDeclaration(), outer);
1453        }
1454    
1455        @Nullable
1456        public static ClassDescriptor getContainingClass(@NotNull JetScope scope) {
1457            return getParentOfType(scope.getContainingDeclaration(), ClassDescriptor.class, false);
1458        }
1459    
1460        public static void checkParameterHasNoValOrVar(
1461                @NotNull BindingTrace trace,
1462                @NotNull JetParameter parameter,
1463                @NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory
1464        ) {
1465            ASTNode valOrVarNode = parameter.getValOrVarNode();
1466            if (valOrVarNode != null) {
1467                trace.report(diagnosticFactory.on(valOrVarNode.getPsi(), ((JetKeywordToken) valOrVarNode.getElementType())));
1468            }
1469        }
1470    
1471        private static void checkConstructorParameterHasNoModifier(
1472                @NotNull BindingTrace trace,
1473                @NotNull JetParameter parameter
1474        ) {
1475            // If is not a property, then it must have no modifier
1476            if (!parameter.hasValOrVarNode()) {
1477                checkParameterHasNoModifier(trace, parameter);
1478            }
1479        }
1480    
1481        public static void checkParameterHasNoModifier(
1482                @NotNull BindingTrace trace,
1483                @NotNull JetParameter parameter
1484        ) {
1485            ModifiersChecker.reportIllegalModifiers(parameter.getModifierList(), MODIFIERS_ILLEGAL_ON_PARAMETERS, trace);
1486        }
1487    
1488        public static void resolvePackageHeader(
1489                @NotNull JetPackageDirective packageDirective,
1490                @NotNull ModuleDescriptor module,
1491                @NotNull BindingTrace trace
1492        ) {
1493            for (JetSimpleNameExpression nameExpression : packageDirective.getPackageNames()) {
1494                FqName fqName = packageDirective.getFqName(nameExpression);
1495    
1496                PackageViewDescriptor packageView = module.getPackage(fqName);
1497                assert packageView != null : "package not found: " + fqName;
1498                trace.record(REFERENCE_TARGET, nameExpression, packageView);
1499    
1500                PackageViewDescriptor parentPackageView = packageView.getContainingDeclaration();
1501                assert parentPackageView != null : "package has no parent: " + packageView;
1502                trace.record(RESOLUTION_SCOPE, nameExpression, parentPackageView.getMemberScope());
1503            }
1504        }
1505    
1506        public static void registerFileInPackage(@NotNull BindingTrace trace, @NotNull JetFile file) {
1507            // Register files corresponding to this package
1508            // The trace currently does not support bi-di multimaps that would handle this task nicer
1509            FqName fqName = file.getPackageFqName();
1510            Collection<JetFile> files = trace.get(PACKAGE_TO_FILES, fqName);
1511            if (files == null) {
1512                files = Sets.newIdentityHashSet();
1513            }
1514            files.add(file);
1515            trace.record(BindingContext.PACKAGE_TO_FILES, fqName, files);
1516        }
1517    }