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 isDefaultObjectConstraint;
655    
656            private UpperBoundCheckerTask(JetTypeReference upperBound, JetType upperBoundType, boolean defaultObjectConstraint) {
657                this.upperBound = upperBound;
658                this.upperBoundType = upperBoundType;
659                isDefaultObjectConstraint = defaultObjectConstraint;
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                reportUnsupportedDefaultObjectConstraint(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.isDefaultObjectConstraint()));
702                }
703    
704                if (typeParameterDescriptor != null) {
705                    trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
706                    if (bound != null) {
707                        if (constraint.isDefaultObjectConstraint()) {
708                            // Default object bounds are not supported
709                        }
710                        else {
711                            typeParameterDescriptor.addUpperBound(bound);
712                        }
713                    }
714                }
715            }
716    
717            for (TypeParameterDescriptorImpl parameter : parameters) {
718                parameter.addDefaultUpperBound();
719    
720                parameter.setInitialized();
721    
722                checkConflictingUpperBounds(trace, parameter, typeParameters.get(parameter.getIndex()));
723            }
724    
725            if (!(declaration instanceof JetClass)) {
726                for (UpperBoundCheckerTask checkerTask : deferredUpperBoundCheckerTasks) {
727                    checkUpperBoundType(checkerTask.upperBound, checkerTask.upperBoundType, checkerTask.isDefaultObjectConstraint, trace);
728                }
729    
730                checkNamesInConstraints(declaration, descriptor, scope, trace);
731            }
732        }
733    
734        public static void checkConflictingUpperBounds(
735                @NotNull BindingTrace trace,
736                @NotNull TypeParameterDescriptor parameter,
737                @NotNull JetTypeParameter typeParameter
738        ) {
739            if (KotlinBuiltIns.isNothing(parameter.getUpperBoundsAsType())) {
740                trace.report(CONFLICTING_UPPER_BOUNDS.on(typeParameter, parameter));
741            }
742    
743            JetType classObjectType = parameter.getClassObjectType();
744            if (classObjectType != null && KotlinBuiltIns.isNothing(classObjectType)) {
745                trace.report(CONFLICTING_DEFAULT_OBJECT_UPPER_BOUNDS.on(typeParameter, parameter));
746            }
747        }
748    
749        public void checkNamesInConstraints(
750                @NotNull JetTypeParameterListOwner declaration,
751                @NotNull DeclarationDescriptor descriptor,
752                @NotNull JetScope scope,
753                @NotNull BindingTrace trace
754        ) {
755            for (JetTypeConstraint constraint : declaration.getTypeConstraints()) {
756                JetSimpleNameExpression nameExpression = constraint.getSubjectTypeParameterName();
757                if (nameExpression == null) continue;
758    
759                Name name = nameExpression.getReferencedNameAsName();
760    
761                ClassifierDescriptor classifier = scope.getClassifier(name);
762                if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == descriptor) continue;
763    
764                if (classifier != null) {
765                    // To tell the user that we look only for locally defined type parameters
766                    trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(nameExpression, constraint, declaration));
767                    trace.record(BindingContext.REFERENCE_TARGET, nameExpression, classifier);
768                }
769                else {
770                    trace.report(UNRESOLVED_REFERENCE.on(nameExpression, nameExpression));
771                }
772    
773                JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
774                if (boundTypeReference != null) {
775                    typeResolver.resolveType(scope, boundTypeReference, trace, true);
776                }
777            }
778        }
779    
780        public static void reportUnsupportedDefaultObjectConstraint(BindingTrace trace, JetTypeConstraint constraint) {
781            if (constraint.isDefaultObjectConstraint()) {
782                trace.report(UNSUPPORTED.on(constraint, "Default objects constraints are not supported yet"));
783            }
784        }
785    
786        public static void checkUpperBoundType(
787                JetTypeReference upperBound,
788                @NotNull JetType upperBoundType,
789                boolean isDefaultObjectConstraint,
790                BindingTrace trace
791        ) {
792            if (!TypeUtils.canHaveSubtypes(JetTypeChecker.DEFAULT, upperBoundType)) {
793                if (isDefaultObjectConstraint) {
794                    trace.report(FINAL_DEFAULT_OBJECT_UPPER_BOUND.on(upperBound, upperBoundType));
795                }
796                else {
797                    trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
798                }
799            }
800            if (TypesPackage.isDynamic(upperBoundType)) {
801                trace.report(DYNAMIC_UPPER_BOUND.on(upperBound));
802            }
803        }
804    
805        @NotNull
806        public VariableDescriptor resolveLocalVariableDescriptor(
807                @NotNull JetScope scope,
808                @NotNull JetParameter parameter,
809                BindingTrace trace
810        ) {
811            JetType type = resolveParameterType(scope, parameter, trace);
812            return resolveLocalVariableDescriptor(parameter, type, trace, scope);
813        }
814    
815        private JetType resolveParameterType(JetScope scope, JetParameter parameter, BindingTrace trace) {
816            JetTypeReference typeReference = parameter.getTypeReference();
817            JetType type;
818            if (typeReference != null) {
819                type = typeResolver.resolveType(scope, typeReference, trace, true);
820            }
821            else {
822                // Error is reported by the parser
823                type = ErrorUtils.createErrorType("Annotation is absent");
824            }
825            if (parameter.hasModifier(VARARG_KEYWORD)) {
826                return getVarargParameterType(type);
827            }
828            return type;
829        }
830    
831        public VariableDescriptor resolveLocalVariableDescriptor(
832                @NotNull JetParameter parameter,
833                @NotNull JetType type,
834                BindingTrace trace,
835                @NotNull JetScope scope
836        ) {
837            VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
838                    scope.getContainingDeclaration(),
839                    annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
840                    JetPsiUtil.safeName(parameter.getName()),
841                    type,
842                    false,
843                    toSourceElement(parameter)
844            );
845            trace.record(BindingContext.VALUE_PARAMETER, parameter, variableDescriptor);
846            return variableDescriptor;
847        }
848    
849        @NotNull
850        public VariableDescriptor resolveLocalVariableDescriptor(
851                JetScope scope,
852                JetVariableDeclaration variable,
853                DataFlowInfo dataFlowInfo,
854                BindingTrace trace
855        ) {
856            DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration();
857            // SCRIPT: Create property descriptors
858            if (JetPsiUtil.isScriptDeclaration(variable)) {
859                PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
860                        containingDeclaration,
861                        annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
862                        Modality.FINAL,
863                        Visibilities.INTERNAL,
864                        variable.isVar(),
865                        JetPsiUtil.safeName(variable.getName()),
866                        CallableMemberDescriptor.Kind.DECLARATION,
867                        toSourceElement(variable)
868                );
869    
870                JetType type =
871                        getVariableType(propertyDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
872    
873                ReceiverParameterDescriptor receiverParameter = ((ScriptDescriptor) containingDeclaration).getThisAsReceiverParameter();
874                propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), receiverParameter, (JetType) null);
875                initializeWithDefaultGetterSetter(propertyDescriptor);
876                trace.record(BindingContext.VARIABLE, variable, propertyDescriptor);
877                return propertyDescriptor;
878            }
879            else {
880                VariableDescriptorImpl variableDescriptor =
881                        resolveLocalVariableDescriptorWithType(scope, variable, null, trace);
882    
883                JetType type =
884                        getVariableType(variableDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
885                variableDescriptor.setOutType(type);
886                return variableDescriptor;
887            }
888        }
889    
890        private static void initializeWithDefaultGetterSetter(PropertyDescriptorImpl propertyDescriptor) {
891            PropertyGetterDescriptorImpl getter = propertyDescriptor.getGetter();
892            if (getter == null && !Visibilities.isPrivate(propertyDescriptor.getVisibility())) {
893                getter = DescriptorFactory.createDefaultGetter(propertyDescriptor);
894                getter.initialize(propertyDescriptor.getType());
895            }
896    
897            PropertySetterDescriptor setter = propertyDescriptor.getSetter();
898            if (setter == null && propertyDescriptor.isVar()) {
899                setter = DescriptorFactory.createDefaultSetter(propertyDescriptor);
900            }
901            propertyDescriptor.initialize(getter, setter);
902        }
903    
904        @NotNull
905        public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(
906                @NotNull JetScope scope,
907                @NotNull JetVariableDeclaration variable,
908                @Nullable JetType type,
909                @NotNull BindingTrace trace
910        ) {
911            VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
912                    scope.getContainingDeclaration(),
913                    annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
914                    JetPsiUtil.safeName(variable.getName()),
915                    type,
916                    variable.isVar(),
917                    toSourceElement(variable)
918            );
919            trace.record(BindingContext.VARIABLE, variable, variableDescriptor);
920            return variableDescriptor;
921        }
922    
923        @NotNull
924        public PropertyDescriptor resolvePropertyDescriptor(
925                @NotNull DeclarationDescriptor containingDeclaration,
926                @NotNull JetScope scope,
927                @NotNull JetProperty property,
928                @NotNull BindingTrace trace,
929                @NotNull DataFlowInfo dataFlowInfo
930        ) {
931            JetModifierList modifierList = property.getModifierList();
932            boolean isVar = property.isVar();
933    
934            boolean hasBody = hasBody(property);
935            Modality modality = containingDeclaration instanceof ClassDescriptor
936                                ? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, hasBody))
937                                : Modality.FINAL;
938            Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
939            PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
940                    containingDeclaration,
941                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
942                    modality,
943                    visibility,
944                    isVar,
945                    JetPsiUtil.safeName(property.getName()),
946                    CallableMemberDescriptor.Kind.DECLARATION,
947                    toSourceElement(property)
948            );
949    
950            List<TypeParameterDescriptorImpl> typeParameterDescriptors;
951            JetScope scopeWithTypeParameters;
952            JetType receiverType = null;
953    
954            {
955                List<JetTypeParameter> typeParameters = property.getTypeParameters();
956                if (typeParameters.isEmpty()) {
957                    scopeWithTypeParameters = scope;
958                    typeParameterDescriptors = Collections.emptyList();
959                }
960                else {
961                    WritableScope writableScope = new WritableScopeImpl(
962                            scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace),
963                            "Scope with type parameters of a property");
964                    typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(propertyDescriptor, writableScope, typeParameters,
965                                                                                          trace);
966                    writableScope.changeLockLevel(WritableScope.LockLevel.READING);
967                    resolveGenericBounds(property, propertyDescriptor, writableScope, typeParameterDescriptors, trace);
968                    scopeWithTypeParameters = writableScope;
969                }
970    
971                JetTypeReference receiverTypeRef = property.getReceiverTypeReference();
972                if (receiverTypeRef != null) {
973                    receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef, trace, true);
974                }
975            }
976    
977            ReceiverParameterDescriptor receiverDescriptor =
978                    DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
979    
980            ReceiverParameterDescriptor implicitInitializerReceiver = property.hasDelegate() ? NO_RECEIVER_PARAMETER : receiverDescriptor;
981    
982            JetScope propertyScope = JetScopeUtils.getPropertyDeclarationInnerScope(propertyDescriptor, scope, typeParameterDescriptors,
983                                                                                    implicitInitializerReceiver, trace);
984    
985            JetType type = getVariableType(propertyDescriptor, propertyScope, property, dataFlowInfo, true, trace);
986    
987            propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration),
988                                       receiverDescriptor);
989    
990            PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
991            PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
992    
993            propertyDescriptor.initialize(getter, setter);
994    
995            trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
996            return propertyDescriptor;
997        }
998    
999        /*package*/
1000        static boolean hasBody(JetProperty property) {
1001            boolean hasBody = property.hasDelegateExpressionOrInitializer();
1002            if (!hasBody) {
1003                JetPropertyAccessor getter = property.getGetter();
1004                if (getter != null && getter.hasBody()) {
1005                    hasBody = true;
1006                }
1007                JetPropertyAccessor setter = property.getSetter();
1008                if (!hasBody && setter != null && setter.hasBody()) {
1009                    hasBody = true;
1010                }
1011            }
1012            return hasBody;
1013        }
1014    
1015        @NotNull
1016        private JetType getVariableType(
1017                @NotNull final VariableDescriptorImpl variableDescriptor,
1018                @NotNull final JetScope scope,
1019                @NotNull final JetVariableDeclaration variable,
1020                @NotNull final DataFlowInfo dataFlowInfo,
1021                boolean notLocal,
1022                @NotNull final BindingTrace trace
1023        ) {
1024            JetTypeReference propertyTypeRef = variable.getTypeReference();
1025    
1026            boolean hasDelegate = variable instanceof JetProperty && ((JetProperty) variable).hasDelegateExpression();
1027            if (propertyTypeRef == null) {
1028                if (!variable.hasInitializer()) {
1029                    if (hasDelegate && variableDescriptor instanceof PropertyDescriptor) {
1030                        final JetProperty property = (JetProperty) variable;
1031                        if (property.hasDelegateExpression()) {
1032                            return DeferredType.createRecursionIntolerant(
1033                                    storageManager,
1034                                    trace,
1035                                    new Function0<JetType>() {
1036                                        @Override
1037                                        public JetType invoke() {
1038                                            return resolveDelegatedPropertyType(property, (PropertyDescriptor) variableDescriptor, scope,
1039                                                                                property.getDelegateExpression(), dataFlowInfo, trace);
1040                                        }
1041                                    });
1042                        }
1043                    }
1044                    if (!notLocal) {
1045                        trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable));
1046                    }
1047                    return ErrorUtils.createErrorType("No type, no body");
1048                }
1049                else {
1050                    if (notLocal) {
1051                        return DeferredType.createRecursionIntolerant(
1052                                storageManager,
1053                                trace,
1054                                new Function0<JetType>() {
1055                                    @Override
1056                                    public JetType invoke() {
1057                                        JetType initializerType = resolveInitializerType(scope, variable.getInitializer(), dataFlowInfo, trace);
1058                                        setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, initializerType, trace);
1059                                        return transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace);
1060                                    }
1061                                }
1062                        );
1063                    }
1064                    else {
1065                        JetType initializerType = resolveInitializerType(scope, variable.getInitializer(), dataFlowInfo, trace);
1066                        setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, initializerType, trace);
1067                        return initializerType;
1068                    }
1069                }
1070            }
1071            else {
1072                JetType type = typeResolver.resolveType(scope, propertyTypeRef, trace, true);
1073                setConstantForVariableIfNeeded(variableDescriptor, scope, variable, dataFlowInfo, type, trace);
1074                return type;
1075            }
1076        }
1077    
1078        private void setConstantForVariableIfNeeded(
1079                @NotNull VariableDescriptorImpl variableDescriptor,
1080                @NotNull final JetScope scope,
1081                @NotNull final JetVariableDeclaration variable,
1082                @NotNull final DataFlowInfo dataFlowInfo,
1083                @NotNull final JetType variableType,
1084                @NotNull final BindingTrace trace
1085        ) {
1086            if (!shouldRecordInitializerForProperty(variableDescriptor, variableType)) return;
1087    
1088            if (!variable.hasInitializer()) return;
1089    
1090            variableDescriptor.setCompileTimeInitializer(
1091                storageManager.createRecursionTolerantNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
1092                    @Nullable
1093                    @Override
1094                    public CompileTimeConstant<?> invoke() {
1095                        JetExpression initializer = variable.getInitializer();
1096                        JetType initializerType = expressionTypingServices.safeGetType(scope, initializer, variableType, dataFlowInfo, trace);
1097                        CompileTimeConstant<?> constant = ConstantExpressionEvaluator.evaluate(initializer, trace, initializerType);
1098                        if (constant instanceof IntegerValueTypeConstant) {
1099                            return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) constant, initializerType);
1100                        }
1101                        return constant;
1102                    }
1103                }, null)
1104            );
1105        }
1106    
1107        @NotNull
1108        private JetType resolveDelegatedPropertyType(
1109                @NotNull JetProperty property,
1110                @NotNull PropertyDescriptor propertyDescriptor,
1111                @NotNull JetScope scope,
1112                @NotNull JetExpression delegateExpression,
1113                @NotNull DataFlowInfo dataFlowInfo,
1114                @NotNull BindingTrace trace
1115        ) {
1116            JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, scope, trace);
1117    
1118            JetType type = delegatedPropertyResolver.resolveDelegateExpression(
1119                    delegateExpression, property, propertyDescriptor, scope, accessorScope, trace, dataFlowInfo);
1120    
1121            if (type != null) {
1122                JetType getterReturnType = delegatedPropertyResolver
1123                        .getDelegatedPropertyGetMethodReturnType(propertyDescriptor, delegateExpression, type, trace, accessorScope);
1124                if (getterReturnType != null) {
1125                    return getterReturnType;
1126                }
1127            }
1128            return ErrorUtils.createErrorType("Type from delegate");
1129        }
1130    
1131        @Nullable
1132        private static JetType transformAnonymousTypeIfNeeded(
1133                @NotNull DeclarationDescriptorWithVisibility descriptor,
1134                @NotNull JetNamedDeclaration declaration,
1135                @NotNull JetType type,
1136                @NotNull BindingTrace trace
1137        ) {
1138            ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
1139            if (classifierDescriptor == null || !DescriptorUtils.isAnonymousObject(classifierDescriptor)) {
1140                return type;
1141            }
1142    
1143            boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null;
1144            boolean isLocal = DescriptorUtils.isLocal(descriptor);
1145            Visibility visibility = descriptor.getVisibility();
1146            boolean transformNeeded = !isLocal && !visibility.isPublicAPI()
1147                                      && !(definedInClass && Visibilities.isPrivate(visibility));
1148            if (transformNeeded) {
1149                if (type.getConstructor().getSupertypes().size() == 1) {
1150                    assert type.getArguments().isEmpty() : "Object expression couldn't have any type parameters!";
1151                    return type.getConstructor().getSupertypes().iterator().next();
1152                }
1153                else {
1154                    trace.report(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED.on(declaration, type.getConstructor().getSupertypes()));
1155                }
1156            }
1157            return type;
1158        }
1159    
1160        @NotNull
1161        private JetType resolveInitializerType(
1162                @NotNull JetScope scope,
1163                @NotNull JetExpression initializer,
1164                @NotNull DataFlowInfo dataFlowInfo,
1165                @NotNull BindingTrace trace
1166        ) {
1167            return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
1168        }
1169    
1170        @Nullable
1171        private PropertySetterDescriptor resolvePropertySetterDescriptor(
1172                @NotNull JetScope scope,
1173                @NotNull JetProperty property,
1174                @NotNull PropertyDescriptor propertyDescriptor,
1175                BindingTrace trace
1176        ) {
1177            JetPropertyAccessor setter = property.getSetter();
1178            PropertySetterDescriptorImpl setterDescriptor = null;
1179            if (setter != null) {
1180                Annotations annotations =
1181                        annotationResolver.resolveAnnotationsWithoutArguments(scope, setter.getModifierList(), trace);
1182                JetParameter parameter = setter.getParameter();
1183    
1184                setterDescriptor = new PropertySetterDescriptorImpl(propertyDescriptor, annotations,
1185                                                                    resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
1186                                                                    resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
1187                                                                    setter.hasBody(), false,
1188                                                                    CallableMemberDescriptor.Kind.DECLARATION, null, toSourceElement(setter));
1189                if (parameter != null) {
1190    
1191                    // This check is redundant: the parser does not allow a default value, but we'll keep it just in case
1192                    if (parameter.hasDefaultValue()) {
1193                        trace.report(SETTER_PARAMETER_WITH_DEFAULT_VALUE.on(parameter.getDefaultValue()));
1194                    }
1195    
1196                    JetType type;
1197                    JetTypeReference typeReference = parameter.getTypeReference();
1198                    if (typeReference == null) {
1199                        type = propertyDescriptor.getType(); // TODO : this maybe unknown at this point
1200                    }
1201                    else {
1202                        type = typeResolver.resolveType(scope, typeReference, trace, true);
1203                        JetType inType = propertyDescriptor.getType();
1204                        if (inType != null) {
1205                            if (!TypeUtils.equalTypes(type, inType)) {
1206                                trace.report(WRONG_SETTER_PARAMETER_TYPE.on(typeReference, inType, type));
1207                            }
1208                        }
1209                        else {
1210                            // TODO : the same check may be needed later???
1211                        }
1212                    }
1213    
1214                    ValueParameterDescriptorImpl valueParameterDescriptor =
1215                            resolveValueParameterDescriptor(scope, setterDescriptor, parameter, 0, type, trace);
1216                    setterDescriptor.initialize(valueParameterDescriptor);
1217                }
1218                else {
1219                    setterDescriptor.initializeDefault();
1220                }
1221    
1222                trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
1223            }
1224            else if (property.isVar()) {
1225                setterDescriptor = DescriptorFactory.createSetter(propertyDescriptor, !property.hasDelegate());
1226            }
1227    
1228            if (!property.isVar()) {
1229                if (setter != null) {
1230                    //                trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
1231                    trace.report(VAL_WITH_SETTER.on(setter));
1232                }
1233            }
1234            return setterDescriptor;
1235        }
1236    
1237        @Nullable
1238        private PropertyGetterDescriptorImpl resolvePropertyGetterDescriptor(
1239                @NotNull JetScope scope,
1240                @NotNull JetProperty property,
1241                @NotNull PropertyDescriptor propertyDescriptor,
1242                BindingTrace trace
1243        ) {
1244            PropertyGetterDescriptorImpl getterDescriptor;
1245            JetPropertyAccessor getter = property.getGetter();
1246            if (getter != null) {
1247                Annotations annotations =
1248                        annotationResolver.resolveAnnotationsWithoutArguments(scope, getter.getModifierList(), trace);
1249    
1250                JetType outType = propertyDescriptor.getType();
1251                JetType returnType = outType;
1252                JetTypeReference returnTypeReference = getter.getReturnTypeReference();
1253                if (returnTypeReference != null) {
1254                    returnType = typeResolver.resolveType(scope, returnTypeReference, trace, true);
1255                    if (outType != null && !TypeUtils.equalTypes(returnType, outType)) {
1256                        trace.report(WRONG_GETTER_RETURN_TYPE.on(returnTypeReference, propertyDescriptor.getReturnType(), outType));
1257                    }
1258                }
1259    
1260                getterDescriptor = new PropertyGetterDescriptorImpl(propertyDescriptor, annotations,
1261                                                                    resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
1262                                                                    resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
1263                                                                    getter.hasBody(), false,
1264                                                                    CallableMemberDescriptor.Kind.DECLARATION, null, toSourceElement(getter));
1265                getterDescriptor.initialize(returnType);
1266                trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
1267            }
1268            else {
1269                getterDescriptor = DescriptorFactory.createGetter(propertyDescriptor, !property.hasDelegate());
1270                getterDescriptor.initialize(propertyDescriptor.getType());
1271            }
1272            return getterDescriptor;
1273        }
1274    
1275        @NotNull
1276        private ConstructorDescriptorImpl createConstructorDescriptor(
1277                @NotNull JetScope scope,
1278                @NotNull ClassDescriptor classDescriptor,
1279                boolean isPrimary,
1280                @Nullable JetModifierList modifierList,
1281                @NotNull JetDeclaration declarationToTrace,
1282                List<TypeParameterDescriptor> typeParameters, @NotNull List<JetParameter> valueParameters, BindingTrace trace
1283        ) {
1284            ConstructorDescriptorImpl constructorDescriptor = ConstructorDescriptorImpl.create(
1285                    classDescriptor,
1286                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
1287                    isPrimary,
1288                    toSourceElement(declarationToTrace)
1289            );
1290            trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor);
1291            WritableScopeImpl parameterScope = new WritableScopeImpl(
1292                    scope, constructorDescriptor, new TraceBasedRedeclarationHandler(trace), "Scope with value parameters of a constructor");
1293            parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
1294            ConstructorDescriptorImpl constructor = constructorDescriptor.initialize(
1295                    typeParameters,
1296                    resolveValueParameters(constructorDescriptor, parameterScope, valueParameters, trace),
1297                    resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor))
1298            );
1299            if (isAnnotationClass(classDescriptor)) {
1300                CompileTimeConstantUtils.checkConstructorParametersType(valueParameters, trace);
1301            }
1302            return constructor;
1303        }
1304    
1305        @Nullable
1306        public ConstructorDescriptorImpl resolvePrimaryConstructorDescriptor(
1307                @NotNull JetScope scope,
1308                @NotNull ClassDescriptor classDescriptor,
1309                @NotNull JetClass classElement,
1310                BindingTrace trace
1311        ) {
1312            if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) return null;
1313            return createConstructorDescriptor(
1314                    scope,
1315                    classDescriptor,
1316                    true,
1317                    classElement.getPrimaryConstructorModifierList(),
1318                    classElement,
1319                    classDescriptor.getTypeConstructor().getParameters(), classElement.getPrimaryConstructorParameters(), trace);
1320        }
1321    
1322        @NotNull
1323        public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
1324                @NotNull ClassDescriptor classDescriptor,
1325                @NotNull ValueParameterDescriptor valueParameter,
1326                @NotNull JetScope scope,
1327                @NotNull JetParameter parameter, BindingTrace trace
1328        ) {
1329            JetType type = resolveParameterType(scope, parameter, trace);
1330            Name name = parameter.getNameAsSafeName();
1331            boolean isMutable = parameter.isMutable();
1332            JetModifierList modifierList = parameter.getModifierList();
1333    
1334            if (modifierList != null) {
1335                if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
1336                    trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(parameter));
1337                }
1338            }
1339    
1340            PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
1341                    classDescriptor,
1342                    valueParameter.getAnnotations(),
1343                    resolveModalityFromModifiers(parameter, Modality.FINAL),
1344                    resolveVisibilityFromModifiers(parameter, getDefaultVisibility(parameter, classDescriptor)),
1345                    isMutable,
1346                    name,
1347                    CallableMemberDescriptor.Kind.DECLARATION,
1348                    toSourceElement(parameter)
1349            );
1350            propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
1351                                       getDispatchReceiverParameterIfNeeded(classDescriptor), NO_RECEIVER_PARAMETER);
1352    
1353            PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor);
1354            PropertySetterDescriptor setter =
1355                    propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor) : null;
1356    
1357            propertyDescriptor.initialize(getter, setter);
1358            getter.initialize(propertyDescriptor.getType());
1359    
1360            trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
1361            trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
1362            return propertyDescriptor;
1363        }
1364    
1365        public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, @NotNull BindingTrace trace) {
1366            if (type.isError()) return;
1367    
1368            JetTypeElement typeElement = typeReference.getTypeElement();
1369            if (typeElement == null) return;
1370    
1371            List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
1372            List<TypeProjection> arguments = type.getArguments();
1373            assert parameters.size() == arguments.size();
1374    
1375            List<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
1376    
1377            // A type reference from Kotlin code can yield a flexible type only if it's `ft<T1, T2>`, whose bounds should not be checked
1378            if (TypesPackage.isFlexible(type) && !TypesPackage.isDynamic(type)) {
1379                assert jetTypeArguments.size() == 2
1380                        : "Flexible type cannot be denoted in Kotlin otherwise than as ft<T1, T2>, but was: "
1381                          + JetPsiUtil.getElementTextWithContext(typeReference);
1382                // it's really ft<Foo, Bar>
1383                Flexibility flexibility = TypesPackage.flexibility(type);
1384                checkBounds(jetTypeArguments.get(0), flexibility.getLowerBound(), trace);
1385                checkBounds(jetTypeArguments.get(1), flexibility.getUpperBound(), trace);
1386                return;
1387            }
1388    
1389            assert jetTypeArguments.size() == arguments.size() : typeElement.getText() + ": " + jetTypeArguments + " - " + arguments;
1390    
1391            TypeSubstitutor substitutor = TypeSubstitutor.create(type);
1392            for (int i = 0; i < jetTypeArguments.size(); i++) {
1393                JetTypeReference jetTypeArgument = jetTypeArguments.get(i);
1394    
1395                if (jetTypeArgument == null) continue;
1396    
1397                JetType typeArgument = arguments.get(i).getType();
1398                checkBounds(jetTypeArgument, typeArgument, trace);
1399    
1400                TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
1401                checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace);
1402            }
1403        }
1404    
1405        public static void checkBounds(
1406                @NotNull JetTypeReference jetTypeArgument,
1407                @NotNull JetType typeArgument,
1408                @NotNull TypeParameterDescriptor typeParameterDescriptor,
1409                @NotNull TypeSubstitutor substitutor,
1410                @NotNull BindingTrace trace
1411        ) {
1412            for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
1413                JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
1414                if (!JetTypeChecker.DEFAULT.isSubtypeOf(typeArgument, substitutedBound)) {
1415                    trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument));
1416                }
1417            }
1418        }
1419    
1420        public static boolean checkHasOuterClassInstance(
1421                @NotNull JetScope scope,
1422                @NotNull BindingTrace trace,
1423                @NotNull PsiElement reportErrorsOn,
1424                @NotNull ClassDescriptor target
1425        ) {
1426            ClassDescriptor classDescriptor = getContainingClass(scope);
1427    
1428            if (!isInsideOuterClassOrItsSubclass(classDescriptor, target)) {
1429                return true;
1430            }
1431    
1432            while (classDescriptor != null) {
1433                if (isSubclass(classDescriptor, target)) {
1434                    return true;
1435                }
1436    
1437                if (isStaticNestedClass(classDescriptor)) {
1438                    trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
1439                    return false;
1440                }
1441                classDescriptor = getParentOfType(classDescriptor, ClassDescriptor.class, true);
1442            }
1443            return true;
1444        }
1445    
1446        private static boolean isInsideOuterClassOrItsSubclass(@Nullable DeclarationDescriptor nested, @NotNull ClassDescriptor outer) {
1447            if (nested == null) return false;
1448    
1449            if (nested instanceof ClassDescriptor && isSubclass((ClassDescriptor) nested, outer)) return true;
1450    
1451            return isInsideOuterClassOrItsSubclass(nested.getContainingDeclaration(), outer);
1452        }
1453    
1454        @Nullable
1455        public static ClassDescriptor getContainingClass(@NotNull JetScope scope) {
1456            return getParentOfType(scope.getContainingDeclaration(), ClassDescriptor.class, false);
1457        }
1458    
1459        public static void checkParameterHasNoValOrVar(
1460                @NotNull BindingTrace trace,
1461                @NotNull JetParameter parameter,
1462                @NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory
1463        ) {
1464            ASTNode valOrVarNode = parameter.getValOrVarNode();
1465            if (valOrVarNode != null) {
1466                trace.report(diagnosticFactory.on(valOrVarNode.getPsi(), ((JetKeywordToken) valOrVarNode.getElementType())));
1467            }
1468        }
1469    
1470        private static void checkConstructorParameterHasNoModifier(
1471                @NotNull BindingTrace trace,
1472                @NotNull JetParameter parameter
1473        ) {
1474            // If is not a property, then it must have no modifier
1475            if (!parameter.hasValOrVarNode()) {
1476                checkParameterHasNoModifier(trace, parameter);
1477            }
1478        }
1479    
1480        public static void checkParameterHasNoModifier(
1481                @NotNull BindingTrace trace,
1482                @NotNull JetParameter parameter
1483        ) {
1484            ModifiersChecker.reportIllegalModifiers(parameter.getModifierList(), MODIFIERS_ILLEGAL_ON_PARAMETERS, trace);
1485        }
1486    
1487        public static void resolvePackageHeader(
1488                @NotNull JetPackageDirective packageDirective,
1489                @NotNull ModuleDescriptor module,
1490                @NotNull BindingTrace trace
1491        ) {
1492            for (JetSimpleNameExpression nameExpression : packageDirective.getPackageNames()) {
1493                FqName fqName = packageDirective.getFqName(nameExpression);
1494    
1495                PackageViewDescriptor packageView = module.getPackage(fqName);
1496                assert packageView != null : "package not found: " + fqName;
1497                trace.record(REFERENCE_TARGET, nameExpression, packageView);
1498    
1499                PackageViewDescriptor parentPackageView = packageView.getContainingDeclaration();
1500                assert parentPackageView != null : "package has no parent: " + packageView;
1501                trace.record(RESOLUTION_SCOPE, nameExpression, parentPackageView.getMemberScope());
1502            }
1503        }
1504    
1505        public static void registerFileInPackage(@NotNull BindingTrace trace, @NotNull JetFile file) {
1506            // Register files corresponding to this package
1507            // The trace currently does not support bi-di multimaps that would handle this task nicer
1508            FqName fqName = file.getPackageFqName();
1509            Collection<JetFile> files = trace.get(PACKAGE_TO_FILES, fqName);
1510            if (files == null) {
1511                files = Sets.newIdentityHashSet();
1512            }
1513            files.add(file);
1514            trace.record(BindingContext.PACKAGE_TO_FILES, fqName, files);
1515        }
1516    }