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