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