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