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
017package org.jetbrains.jet.lang.resolve;
018
019import com.google.common.collect.Lists;
020import com.google.common.collect.Maps;
021import com.intellij.lang.ASTNode;
022import com.intellij.psi.PsiElement;
023import com.intellij.psi.util.PsiTreeUtil;
024import org.jetbrains.annotations.NotNull;
025import org.jetbrains.annotations.Nullable;
026import org.jetbrains.jet.lang.descriptors.*;
027import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
028import org.jetbrains.jet.lang.descriptors.impl.*;
029import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1;
030import org.jetbrains.jet.lang.psi.*;
031import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
032import org.jetbrains.jet.lang.resolve.name.Name;
033import org.jetbrains.jet.lang.resolve.scopes.JetScope;
034import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
035import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
036import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
037import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
038import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
039import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
040import org.jetbrains.jet.lang.types.*;
041import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
042import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils;
043import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
044import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
045import org.jetbrains.jet.lexer.JetKeywordToken;
046import org.jetbrains.jet.lexer.JetTokens;
047import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
048import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValueWithDefault;
049
050import javax.inject.Inject;
051import java.util.*;
052
053import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
054import static org.jetbrains.jet.lang.diagnostics.Errors.*;
055import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR;
056import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
057import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*;
058import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
059
060public 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}