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