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