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