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