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