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