001    /*
002     * Copyright 2010-2015 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.kotlin.resolve;
018    
019    import com.google.common.collect.Maps;
020    import com.google.common.collect.Sets;
021    import com.intellij.psi.PsiElement;
022    import com.intellij.util.containers.Queue;
023    import kotlin.Unit;
024    import kotlin.jvm.functions.Function1;
025    import org.jetbrains.annotations.NotNull;
026    import org.jetbrains.annotations.Nullable;
027    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
028    import org.jetbrains.kotlin.descriptors.*;
029    import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
030    import org.jetbrains.kotlin.diagnostics.Errors;
031    import org.jetbrains.kotlin.lexer.KtTokens;
032    import org.jetbrains.kotlin.psi.*;
033    import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
034    import org.jetbrains.kotlin.resolve.calls.CallResolver;
035    import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
036    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
037    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
038    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
039    import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
040    import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
041    import org.jetbrains.kotlin.resolve.scopes.*;
042    import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
043    import org.jetbrains.kotlin.types.*;
044    import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
045    import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor;
046    import org.jetbrains.kotlin.types.expressions.ValueParameterResolver;
047    import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
048    import org.jetbrains.kotlin.util.Box;
049    import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
050    import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
051    
052    import java.util.*;
053    
054    import static org.jetbrains.kotlin.diagnostics.Errors.*;
055    import static org.jetbrains.kotlin.resolve.BindingContext.*;
056    import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
057    
058    public class BodyResolver {
059        @NotNull private final AnnotationChecker annotationChecker;
060        @NotNull private final ExpressionTypingServices expressionTypingServices;
061        @NotNull private final CallResolver callResolver;
062        @NotNull private final ObservableBindingTrace trace;
063        @NotNull private final ControlFlowAnalyzer controlFlowAnalyzer;
064        @NotNull private final DeclarationsChecker declarationsChecker;
065        @NotNull private final AnnotationResolver annotationResolver;
066        @NotNull private final DelegatedPropertyResolver delegatedPropertyResolver;
067        @NotNull private final FunctionAnalyzerExtension functionAnalyzerExtension;
068        @NotNull private final ValueParameterResolver valueParameterResolver;
069        @NotNull private final BodyResolveCache bodyResolveCache;
070        @NotNull private final KotlinBuiltIns builtIns;
071    
072        public BodyResolver(
073                @NotNull AnnotationResolver annotationResolver,
074                @NotNull BodyResolveCache bodyResolveCache,
075                @NotNull CallResolver callResolver,
076                @NotNull ControlFlowAnalyzer controlFlowAnalyzer,
077                @NotNull DeclarationsChecker declarationsChecker,
078                @NotNull DelegatedPropertyResolver delegatedPropertyResolver,
079                @NotNull ExpressionTypingServices expressionTypingServices,
080                @NotNull FunctionAnalyzerExtension functionAnalyzerExtension,
081                @NotNull BindingTrace trace,
082                @NotNull ValueParameterResolver valueParameterResolver,
083                @NotNull AnnotationChecker annotationChecker,
084                @NotNull KotlinBuiltIns builtIns
085        ) {
086            this.annotationResolver = annotationResolver;
087            this.bodyResolveCache = bodyResolveCache;
088            this.callResolver = callResolver;
089            this.controlFlowAnalyzer = controlFlowAnalyzer;
090            this.declarationsChecker = declarationsChecker;
091            this.delegatedPropertyResolver = delegatedPropertyResolver;
092            this.expressionTypingServices = expressionTypingServices;
093            this.functionAnalyzerExtension = functionAnalyzerExtension;
094            this.annotationChecker = annotationChecker;
095            this.trace = new ObservableBindingTrace(trace);
096            this.valueParameterResolver = valueParameterResolver;
097            this.builtIns = builtIns;
098        }
099    
100        private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext c) {
101            resolveDelegationSpecifierLists(c);
102    
103            resolvePropertyDeclarationBodies(c);
104    
105            resolveAnonymousInitializers(c);
106            resolvePrimaryConstructorParameters(c);
107            resolveSecondaryConstructors(c);
108    
109            resolveFunctionBodies(c);
110    
111            if (!c.getTopDownAnalysisMode().isLocalDeclarations()) {
112                computeDeferredTypes();
113            }
114        }
115    
116        private void resolveSecondaryConstructors(@NotNull BodiesResolveContext c) {
117            for (Map.Entry<KtSecondaryConstructor, ConstructorDescriptor> entry : c.getSecondaryConstructors().entrySet()) {
118                LexicalScope declaringScope = c.getDeclaringScope(entry.getKey());
119                assert declaringScope != null : "Declaring scope should be registered before body resolve";
120                resolveSecondaryConstructorBody(c.getOuterDataFlowInfo(), trace, entry.getKey(), entry.getValue(), declaringScope);
121            }
122            if (c.getSecondaryConstructors().isEmpty()) return;
123            Set<ConstructorDescriptor> visitedConstructors = Sets.newHashSet();
124            for (Map.Entry<KtSecondaryConstructor, ConstructorDescriptor> entry : c.getSecondaryConstructors().entrySet()) {
125                checkCyclicConstructorDelegationCall(entry.getValue(), visitedConstructors);
126            }
127        }
128    
129        public void resolveSecondaryConstructorBody(
130                @NotNull final DataFlowInfo outerDataFlowInfo,
131                @NotNull final BindingTrace trace,
132                @NotNull final KtSecondaryConstructor constructor,
133                @NotNull final ConstructorDescriptor descriptor,
134                @NotNull LexicalScope declaringScope
135        ) {
136            ForceResolveUtil.forceResolveAllContents(descriptor.getAnnotations());
137    
138            final CallChecker callChecker = new ConstructorHeaderCallChecker(descriptor);
139            resolveFunctionBody(outerDataFlowInfo, trace, constructor, descriptor, declaringScope,
140                                new Function1<LexicalScope, DataFlowInfo>() {
141                                    @Override
142                                    public DataFlowInfo invoke(@NotNull LexicalScope headerInnerScope) {
143                                        return resolveSecondaryConstructorDelegationCall(outerDataFlowInfo, trace, headerInnerScope,
144                                                                                         constructor, descriptor,
145                                                                                         callChecker);
146                                    }
147                                },
148                                callChecker);
149        }
150    
151        @Nullable
152        private DataFlowInfo resolveSecondaryConstructorDelegationCall(
153                @NotNull DataFlowInfo outerDataFlowInfo,
154                @NotNull BindingTrace trace,
155                @NotNull LexicalScope scope,
156                @NotNull KtSecondaryConstructor constructor,
157                @NotNull ConstructorDescriptor descriptor,
158                @NotNull CallChecker callChecker
159        ) {
160            OverloadResolutionResults<?> results = callResolver.resolveConstructorDelegationCall(
161                    trace, scope, outerDataFlowInfo,
162                    descriptor, constructor.getDelegationCall(),
163                    callChecker);
164    
165            if (results != null && results.isSingleResult()) {
166                ResolvedCall<? extends CallableDescriptor> resolvedCall = results.getResultingCall();
167                recordConstructorDelegationCall(trace, descriptor, resolvedCall);
168                return resolvedCall.getDataFlowInfoForArguments().getResultInfo();
169            }
170            return null;
171        }
172    
173        private void checkCyclicConstructorDelegationCall(
174                @NotNull ConstructorDescriptor constructorDescriptor,
175                @NotNull Set<ConstructorDescriptor> visitedConstructors
176        ) {
177            if (visitedConstructors.contains(constructorDescriptor)) return;
178    
179            // if visit constructor that is already in current chain
180            // such constructor is on cycle
181            Set<ConstructorDescriptor> visitedInCurrentChain = Sets.newHashSet();
182            ConstructorDescriptor currentConstructorDescriptor = constructorDescriptor;
183            while (true) {
184                visitedInCurrentChain.add(currentConstructorDescriptor);
185                ConstructorDescriptor delegatedConstructorDescriptor = getDelegatedConstructor(currentConstructorDescriptor);
186                if (delegatedConstructorDescriptor == null) break;
187    
188                // if next delegation call is super or primary constructor or already visited
189                if (!constructorDescriptor.getContainingDeclaration().equals(delegatedConstructorDescriptor.getContainingDeclaration()) ||
190                    delegatedConstructorDescriptor.isPrimary() ||
191                    visitedConstructors.contains(delegatedConstructorDescriptor)) {
192                    break;
193                }
194    
195                if (visitedInCurrentChain.contains(delegatedConstructorDescriptor)) {
196                    reportEachConstructorOnCycle(delegatedConstructorDescriptor);
197                    break;
198                }
199                currentConstructorDescriptor = delegatedConstructorDescriptor;
200            }
201            visitedConstructors.addAll(visitedInCurrentChain);
202        }
203    
204        private void reportEachConstructorOnCycle(@NotNull ConstructorDescriptor startConstructor) {
205            ConstructorDescriptor currentConstructor = startConstructor;
206            do {
207                PsiElement constructorToReport = DescriptorToSourceUtils.descriptorToDeclaration(currentConstructor);
208                if (constructorToReport != null) {
209                    KtConstructorDelegationCall call = ((KtSecondaryConstructor) constructorToReport).getDelegationCall();
210                    assert call.getCalleeExpression() != null
211                            : "Callee expression of delegation call should not be null on cycle as there should be explicit 'this' calls";
212                    trace.report(CYCLIC_CONSTRUCTOR_DELEGATION_CALL.on(call.getCalleeExpression()));
213                }
214    
215                currentConstructor = getDelegatedConstructor(currentConstructor);
216                assert currentConstructor != null : "Delegated constructor should not be null in cycle";
217            }
218            while (startConstructor != currentConstructor);
219        }
220    
221        @Nullable
222        private ConstructorDescriptor getDelegatedConstructor(@NotNull ConstructorDescriptor constructor) {
223            ResolvedCall<ConstructorDescriptor> call = trace.get(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor);
224            return call == null || !call.getStatus().isSuccess() ? null : call.getResultingDescriptor().getOriginal();
225        }
226    
227        public void resolveBodies(@NotNull BodiesResolveContext c) {
228            resolveBehaviorDeclarationBodies(c);
229            controlFlowAnalyzer.process(c);
230            declarationsChecker.process(c);
231            functionAnalyzerExtension.process(c);
232        }
233    
234        private void resolveDelegationSpecifierLists(@NotNull BodiesResolveContext c) {
235            // TODO : Make sure the same thing is not initialized twice
236            for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
237                KtClassOrObject classOrObject = entry.getKey();
238                ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
239    
240                resolveDelegationSpecifierList(c.getOuterDataFlowInfo(), classOrObject, descriptor,
241                                               descriptor.getUnsubstitutedPrimaryConstructor(),
242                                               descriptor.getScopeForClassHeaderResolution(),
243                                               descriptor.getScopeForMemberDeclarationResolution());
244            }
245        }
246    
247        public void resolveDelegationSpecifierList(
248                @NotNull final DataFlowInfo outerDataFlowInfo,
249                @NotNull KtClassOrObject jetClass,
250                @NotNull final ClassDescriptor descriptor,
251                @Nullable final ConstructorDescriptor primaryConstructor,
252                @NotNull LexicalScope scopeForSupertypeResolution,
253                @NotNull final LexicalScope scopeForMemberResolution
254        ) {
255            final LexicalScope scopeForConstructor =
256                    primaryConstructor == null
257                    ? null
258                    : FunctionDescriptorUtil.getFunctionInnerScope(scopeForSupertypeResolution, primaryConstructor, trace);
259            final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
260    
261            final Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap();
262            final ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1];
263            KtVisitorVoid visitor = new KtVisitorVoid() {
264                private void recordSupertype(KtTypeReference typeReference, KotlinType supertype) {
265                    if (supertype == null) return;
266                    supertypes.put(typeReference, supertype);
267                }
268    
269                @Override
270                public void visitDelegationByExpressionSpecifier(@NotNull KtDelegatorByExpressionSpecifier specifier) {
271                    if (descriptor.getKind() == ClassKind.INTERFACE) {
272                        trace.report(DELEGATION_IN_INTERFACE.on(specifier));
273                    }
274                    KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
275                    recordSupertype(specifier.getTypeReference(), supertype);
276                    if (supertype != null) {
277                        DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
278                        if (declarationDescriptor instanceof ClassDescriptor) {
279                            ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
280                            if (classDescriptor.getKind() != ClassKind.INTERFACE) {
281                                trace.report(DELEGATION_NOT_TO_INTERFACE.on(specifier.getTypeReference()));
282                            }
283                        }
284                    }
285                    KtExpression delegateExpression = specifier.getDelegateExpression();
286                    if (delegateExpression != null) {
287                        LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
288                        KotlinType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE;
289                        typeInferrer.getType(scope, delegateExpression, expectedType, outerDataFlowInfo, trace);
290                    }
291                    if (primaryConstructor == null) {
292                        trace.report(UNSUPPORTED.on(specifier, "Delegation without primary constructor is not supported"));
293                    }
294                }
295    
296                @Override
297                public void visitDelegationToSuperCallSpecifier(@NotNull KtDelegatorToSuperCall call) {
298                    KtValueArgumentList valueArgumentList = call.getValueArgumentList();
299                    PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList;
300                    if (descriptor.getKind() == ClassKind.INTERFACE) {
301                        trace.report(SUPERTYPE_INITIALIZED_IN_INTERFACE.on(elementToMark));
302                    }
303                    KtTypeReference typeReference = call.getTypeReference();
304                    if (typeReference == null) return;
305                    if (primaryConstructor == null) {
306                        if (descriptor.getKind() != ClassKind.INTERFACE) {
307                            trace.report(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR.on(call));
308                        }
309                        recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
310                        return;
311                    }
312                    OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
313                            trace, scopeForConstructor,
314                            CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call), NO_EXPECTED_TYPE, outerDataFlowInfo, false);
315                    if (results.isSuccess()) {
316                        KotlinType supertype = results.getResultingDescriptor().getReturnType();
317                        recordSupertype(typeReference, supertype);
318                        ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
319                        if (classDescriptor != null) {
320                            // allow only one delegating constructor
321                            if (primaryConstructorDelegationCall[0] == null) {
322                                primaryConstructorDelegationCall[0] = results.getResultingCall();
323                            }
324                            else {
325                                primaryConstructorDelegationCall[0] = null;
326                            }
327                        }
328                        // Recording type info for callee to use later in JetObjectLiteralExpression
329                        trace.record(PROCESSED, call.getCalleeExpression(), true);
330                        trace.record(EXPRESSION_TYPE_INFO, call.getCalleeExpression(),
331                                     TypeInfoFactoryKt.noTypeInfo(results.getResultingCall().getDataFlowInfoForArguments().getResultInfo()));
332                    }
333                    else {
334                        recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
335                    }
336                }
337    
338                @Override
339                public void visitDelegationToSuperClassSpecifier(@NotNull KtDelegatorToSuperClass specifier) {
340                    KtTypeReference typeReference = specifier.getTypeReference();
341                    KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
342                    recordSupertype(typeReference, supertype);
343                    if (supertype == null) return;
344                    ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype);
345                    if (superClass == null) return;
346                    if (superClass.getKind().isSingleton()) {
347                        // A "singleton in supertype" diagnostic will be reported later
348                        return;
349                    }
350                    if (descriptor.getKind() != ClassKind.INTERFACE &&
351                        descriptor.getUnsubstitutedPrimaryConstructor() != null &&
352                        superClass.getKind() != ClassKind.INTERFACE &&
353                        !superClass.getConstructors().isEmpty() &&
354                        !ErrorUtils.isError(superClass)
355                    ) {
356                        trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
357                    }
358                }
359    
360                @Override
361                public void visitKtElement(@NotNull KtElement element) {
362                    throw new UnsupportedOperationException(element.getText() + " : " + element);
363                }
364            };
365    
366            for (KtDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
367                delegationSpecifier.accept(visitor);
368            }
369    
370            if (DescriptorUtils.isAnnotationClass(descriptor) && jetClass.getDelegationSpecifierList() != null) {
371                trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(jetClass.getDelegationSpecifierList()));
372            }
373    
374            if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
375                recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]);
376            }
377    
378            checkSupertypeList(descriptor, supertypes, jetClass);
379        }
380    
381        // Returns a set of enum or sealed types of which supertypeOwner is an entry or a member
382        @NotNull
383        private static Set<TypeConstructor> getAllowedFinalSupertypes(
384                @NotNull ClassDescriptor descriptor,
385                @NotNull KtClassOrObject jetClass
386        ) {
387            Set<TypeConstructor> parentEnumOrSealed;
388            if (jetClass instanceof KtEnumEntry) {
389                parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor());
390            }
391            else {
392                parentEnumOrSealed = Collections.emptySet();
393                ClassDescriptor currentDescriptor = descriptor;
394                while (currentDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
395                    currentDescriptor = (ClassDescriptor) currentDescriptor.getContainingDeclaration();
396                    if (currentDescriptor.getModality() == Modality.SEALED) {
397                        if (parentEnumOrSealed.isEmpty()) {
398                            parentEnumOrSealed = new HashSet<TypeConstructor>();
399                        }
400                        parentEnumOrSealed.add(currentDescriptor.getTypeConstructor());
401                    }
402                }
403            }
404            return parentEnumOrSealed;
405        }
406    
407        private static void recordConstructorDelegationCall(
408                @NotNull BindingTrace trace,
409                @NotNull ConstructorDescriptor constructor,
410                @NotNull ResolvedCall<?> call
411        ) {
412            //noinspection unchecked
413            trace.record(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor, (ResolvedCall<ConstructorDescriptor>) call);
414        }
415    
416        private void checkSupertypeList(
417                @NotNull ClassDescriptor supertypeOwner,
418                @NotNull Map<KtTypeReference, KotlinType> supertypes,
419                @NotNull KtClassOrObject jetClass
420        ) {
421            Set<TypeConstructor> allowedFinalSupertypes = getAllowedFinalSupertypes(supertypeOwner, jetClass);
422            Set<TypeConstructor> typeConstructors = Sets.newHashSet();
423            boolean classAppeared = false;
424            for (Map.Entry<KtTypeReference, KotlinType> entry : supertypes.entrySet()) {
425                KtTypeReference typeReference = entry.getKey();
426                KotlinType supertype = entry.getValue();
427    
428                KtTypeElement typeElement = typeReference.getTypeElement();
429                if (typeElement instanceof KtFunctionType) {
430                    for (KtParameter parameter : ((KtFunctionType) typeElement).getParameters()) {
431                        PsiElement nameIdentifier = parameter.getNameIdentifier();
432    
433                        if (nameIdentifier != null) {
434                            trace.report(Errors.UNSUPPORTED.on(nameIdentifier, "named parameter in function type in supertype position"));
435                        }
436                    }
437                }
438    
439                boolean addSupertype = true;
440    
441                ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
442                if (classDescriptor != null) {
443                    if (ErrorUtils.isError(classDescriptor)) continue;
444    
445                    if (KotlinBuiltIns.isExactExtensionFunctionType(supertype)) {
446                        trace.report(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE.on(typeReference));
447                    }
448    
449                    if (classDescriptor.getKind() != ClassKind.INTERFACE) {
450                        if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) {
451                            trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference));
452                            addSupertype = false;
453                        }
454                        else if (supertypeOwner.getKind() == ClassKind.INTERFACE &&
455                                 !classAppeared && !DynamicTypesKt.isDynamic(supertype) /* avoid duplicate diagnostics */) {
456                            trace.report(INTERFACE_WITH_SUPERCLASS.on(typeReference));
457                            addSupertype = false;
458                        }
459                        else if (jetClass.hasModifier(KtTokens.DATA_KEYWORD)) {
460                            trace.report(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES.on(typeReference));
461                            addSupertype = false;
462                        }
463                        else if (DescriptorUtils.isSubclass(classDescriptor, builtIns.getThrowable()) &&
464                                 !supertypeOwner.getDeclaredTypeParameters().isEmpty()) {
465                            trace.report(GENERIC_THROWABLE_SUBCLASS.on(jetClass.getTypeParameterList()));
466                            addSupertype = false;
467                        }
468    
469                        if (classAppeared) {
470                            trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference));
471                        }
472                        else {
473                            classAppeared = true;
474                        }
475                    }
476                }
477                else {
478                    trace.report(SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.on(typeReference));
479                }
480    
481                TypeConstructor constructor = supertype.getConstructor();
482                if (addSupertype && !typeConstructors.add(constructor)) {
483                    trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
484                }
485    
486                if (classDescriptor != null && classDescriptor.getKind().isSingleton()) {
487                    if (!DescriptorUtils.isEnumEntry(classDescriptor)) {
488                        trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
489                    }
490                }
491                else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) {
492                    if (classDescriptor.getModality() == Modality.SEALED) {
493                        DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration();
494                        while (containingDescriptor != null && containingDescriptor != classDescriptor) {
495                            containingDescriptor = containingDescriptor.getContainingDeclaration();
496                        }
497                        if (containingDescriptor == null) {
498                            trace.report(SEALED_SUPERTYPE.on(typeReference));
499                        }
500                        else {
501                            trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference));
502                        }
503                    }
504                    else {
505                        trace.report(FINAL_SUPERTYPE.on(typeReference));
506                    }
507                }
508            }
509        }
510    
511        private void resolveAnonymousInitializers(@NotNull BodiesResolveContext c) {
512            for (Map.Entry<KtAnonymousInitializer, ClassDescriptorWithResolutionScopes> entry : c.getAnonymousInitializers().entrySet()) {
513                KtAnonymousInitializer initializer = entry.getKey();
514                ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
515                resolveAnonymousInitializer(c.getOuterDataFlowInfo(), initializer, descriptor);
516            }
517        }
518    
519        public void resolveAnonymousInitializer(
520                @NotNull DataFlowInfo outerDataFlowInfo,
521                @NotNull KtAnonymousInitializer anonymousInitializer,
522                @NotNull ClassDescriptorWithResolutionScopes classDescriptor
523        ) {
524            LexicalScope scopeForInitializers = classDescriptor.getScopeForInitializerResolution();
525            if (!classDescriptor.getConstructors().isEmpty()) {
526                KtExpression body = anonymousInitializer.getBody();
527                if (body != null) {
528                    PreliminaryDeclarationVisitor.Companion.createForDeclaration(
529                            (KtDeclaration) anonymousInitializer.getParent().getParent(), trace);
530                    expressionTypingServices.getTypeInfo(
531                            scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace, /*isStatement = */true
532                    );
533                }
534                processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
535            }
536            else {
537                trace.report(ANONYMOUS_INITIALIZER_IN_INTERFACE.on(anonymousInitializer));
538                processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
539            }
540        }
541    
542        private void processModifiersOnInitializer(@NotNull KtModifierListOwner owner, @NotNull LexicalScope scope) {
543            annotationChecker.check(owner, trace, null);
544            ModifierCheckerCore.INSTANCE$.check(owner, trace, null);
545            KtModifierList modifierList = owner.getModifierList();
546            if (modifierList == null) return;
547    
548            annotationResolver.resolveAnnotationsWithArguments(scope, modifierList, trace);
549        }
550    
551        private void resolvePrimaryConstructorParameters(@NotNull BodiesResolveContext c) {
552            for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
553                KtClassOrObject klass = entry.getKey();
554                ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue();
555                ConstructorDescriptor unsubstitutedPrimaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
556                if (unsubstitutedPrimaryConstructor != null) {
557                    ForceResolveUtil.forceResolveAllContents(unsubstitutedPrimaryConstructor.getAnnotations());
558    
559                    LexicalScope parameterScope = getPrimaryConstructorParametersScope(classDescriptor.getScopeForClassHeaderResolution(),
560                                                                                       unsubstitutedPrimaryConstructor);
561                    valueParameterResolver.resolveValueParameters(klass.getPrimaryConstructorParameters(),
562                                                                  unsubstitutedPrimaryConstructor.getValueParameters(),
563                                                                  parameterScope, c.getOuterDataFlowInfo(), trace);
564                }
565            }
566        }
567    
568        private static LexicalScope getPrimaryConstructorParametersScope(
569                LexicalScope originalScope,
570                final ConstructorDescriptor unsubstitutedPrimaryConstructor
571        ) {
572            return new LexicalScopeImpl(originalScope, unsubstitutedPrimaryConstructor, false, null,
573                                        LexicalScopeKind.DEFAULT_VALUE, RedeclarationHandler.DO_NOTHING,
574                                        new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
575                                            @Override
576                                            public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
577                                                for (ValueParameterDescriptor
578                                                        valueParameterDescriptor : unsubstitutedPrimaryConstructor.getValueParameters()) {
579                                                    handler.addVariableDescriptor(valueParameterDescriptor);
580                                                }
581                                                return Unit.INSTANCE$;
582                                            }
583                                        });
584        }
585    
586        public void resolveProperty(
587                @NotNull BodiesResolveContext c,
588                @NotNull KtProperty property,
589                @NotNull PropertyDescriptor propertyDescriptor
590        ) {
591            computeDeferredType(propertyDescriptor.getReturnType());
592    
593            PreliminaryDeclarationVisitor.Companion.createForDeclaration(property, trace);
594            KtExpression initializer = property.getInitializer();
595            LexicalScope propertyHeaderScope = JetScopeUtils.makeScopeForPropertyHeader(getScopeForProperty(c, property), propertyDescriptor);
596    
597            if (initializer != null) {
598                resolvePropertyInitializer(c.getOuterDataFlowInfo(), property, propertyDescriptor, initializer, propertyHeaderScope);
599            }
600    
601            KtExpression delegateExpression = property.getDelegateExpression();
602            if (delegateExpression != null) {
603                assert initializer == null : "Initializer should be null for delegated property : " + property.getText();
604                resolvePropertyDelegate(c.getOuterDataFlowInfo(), property, propertyDescriptor, delegateExpression, propertyHeaderScope);
605            }
606    
607            resolvePropertyAccessors(c, property, propertyDescriptor);
608        }
609    
610        private void resolvePropertyDeclarationBodies(@NotNull BodiesResolveContext c) {
611    
612            // Member properties
613            Set<KtProperty> processed = Sets.newHashSet();
614            for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
615                if (!(entry.getKey() instanceof KtClass)) continue;
616                KtClass ktClass = (KtClass) entry.getKey();
617                ClassDescriptorWithResolutionScopes classDescriptor = entry.getValue();
618    
619                for (KtProperty property : ktClass.getProperties()) {
620                    PropertyDescriptor propertyDescriptor = c.getProperties().get(property);
621                    assert propertyDescriptor != null;
622    
623                    resolveProperty(c, property, propertyDescriptor);
624                    processed.add(property);
625                }
626            }
627    
628            // Top-level properties & properties of objects
629            for (Map.Entry<KtProperty, PropertyDescriptor> entry : c.getProperties().entrySet()) {
630                KtProperty property = entry.getKey();
631                if (processed.contains(property)) continue;
632    
633                PropertyDescriptor propertyDescriptor = entry.getValue();
634    
635                resolveProperty(c, property, propertyDescriptor);
636            }
637        }
638    
639        private static LexicalScope makeScopeForPropertyAccessor(
640                @NotNull BodiesResolveContext c, @NotNull KtPropertyAccessor accessor, @NotNull PropertyDescriptor descriptor
641        ) {
642            LexicalScope accessorDeclaringScope = c.getDeclaringScope(accessor);
643            assert accessorDeclaringScope != null : "Scope for accessor " + accessor.getText() + " should exists";
644            LexicalScope headerScope = JetScopeUtils.makeScopeForPropertyHeader(accessorDeclaringScope, descriptor);
645            return new LexicalScopeImpl(headerScope, descriptor, true, descriptor.getExtensionReceiverParameter(),
646                                        LexicalScopeKind.PROPERTY_ACCESSOR_BODY);
647        }
648    
649        private void resolvePropertyAccessors(
650                @NotNull BodiesResolveContext c,
651                @NotNull KtProperty property,
652                @NotNull PropertyDescriptor propertyDescriptor
653        ) {
654            ObservableBindingTrace fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor);
655    
656            KtPropertyAccessor getter = property.getGetter();
657            PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
658            if (getter != null && getterDescriptor != null) {
659                LexicalScope accessorScope = makeScopeForPropertyAccessor(c, getter, propertyDescriptor);
660                ForceResolveUtil.forceResolveAllContents(getterDescriptor.getAnnotations());
661                resolveFunctionBody(c.getOuterDataFlowInfo(), fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope);
662            }
663    
664            KtPropertyAccessor setter = property.getSetter();
665            PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
666            if (setter != null && setterDescriptor != null) {
667                LexicalScope accessorScope = makeScopeForPropertyAccessor(c, setter, propertyDescriptor);
668                ForceResolveUtil.forceResolveAllContents(setterDescriptor.getAnnotations());
669                resolveFunctionBody(c.getOuterDataFlowInfo(), fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope);
670            }
671        }
672    
673        private ObservableBindingTrace createFieldTrackingTrace(final PropertyDescriptor propertyDescriptor) {
674            return new ObservableBindingTrace(trace).addHandler(
675                    BindingContext.REFERENCE_TARGET,
676                    new ObservableBindingTrace.RecordHandler<KtReferenceExpression, DeclarationDescriptor>() {
677                @Override
678                public void handleRecord(
679                        WritableSlice<KtReferenceExpression, DeclarationDescriptor> slice,
680                        KtReferenceExpression expression,
681                        DeclarationDescriptor descriptor
682                ) {
683                    if (expression instanceof KtSimpleNameExpression &&
684                        descriptor instanceof SyntheticFieldDescriptor) {
685                        trace.record(BindingContext.BACKING_FIELD_REQUIRED,
686                                     propertyDescriptor);
687                    }
688                }
689            });
690        }
691    
692        private void resolvePropertyDelegate(
693                @NotNull DataFlowInfo outerDataFlowInfo,
694                @NotNull KtProperty property,
695                @NotNull PropertyDescriptor propertyDescriptor,
696                @NotNull KtExpression delegateExpression,
697                @NotNull LexicalScope propertyHeaderScope
698        ) {
699            KtPropertyAccessor getter = property.getGetter();
700            if (getter != null && getter.hasBody()) {
701                trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(getter));
702            }
703    
704            KtPropertyAccessor setter = property.getSetter();
705            if (setter != null && setter.hasBody()) {
706                trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter));
707            }
708    
709            LexicalScope delegateFunctionsScope = JetScopeUtils.makeScopeForDelegateConventionFunctions(propertyHeaderScope, propertyDescriptor);
710    
711            LexicalScope initializerScope = JetScopeUtils.makeScopeForPropertyInitializer(propertyHeaderScope, propertyDescriptor);
712    
713            KotlinType delegateType = delegatedPropertyResolver.resolveDelegateExpression(
714                    delegateExpression, property, propertyDescriptor, initializerScope, trace,
715                    outerDataFlowInfo);
716    
717            delegatedPropertyResolver.resolveDelegatedPropertyGetMethod(propertyDescriptor, delegateExpression, delegateType,
718                                                                        trace, delegateFunctionsScope);
719    
720            if (property.isVar()) {
721                delegatedPropertyResolver.resolveDelegatedPropertySetMethod(propertyDescriptor, delegateExpression, delegateType,
722                                                                            trace, delegateFunctionsScope);
723            }
724    
725            delegatedPropertyResolver.resolveDelegatedPropertyPDMethod(propertyDescriptor, delegateExpression, delegateType,
726                                                                       trace, delegateFunctionsScope);
727        }
728    
729        private void resolvePropertyInitializer(
730                @NotNull DataFlowInfo outerDataFlowInfo,
731                @NotNull KtProperty property,
732                @NotNull PropertyDescriptor propertyDescriptor,
733                @NotNull KtExpression initializer,
734                @NotNull LexicalScope propertyHeader
735        ) {
736            LexicalScope propertyDeclarationInnerScope = JetScopeUtils.makeScopeForPropertyInitializer(propertyHeader, propertyDescriptor);
737            KotlinType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
738            if (propertyDescriptor.getCompileTimeInitializer() == null) {
739                expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer,
740                                                 outerDataFlowInfo, trace);
741            }
742        }
743    
744        @NotNull
745        private static LexicalScope getScopeForProperty(@NotNull BodiesResolveContext c, @NotNull KtProperty property) {
746            LexicalScope scope = c.getDeclaringScope(property);
747            assert scope != null : "Scope for property " + property.getText() + " should exists";
748            return scope;
749        }
750    
751        private void resolveFunctionBodies(@NotNull BodiesResolveContext c) {
752            for (Map.Entry<KtNamedFunction, SimpleFunctionDescriptor> entry : c.getFunctions().entrySet()) {
753                KtNamedFunction declaration = entry.getKey();
754    
755                LexicalScope scope = c.getDeclaringScope(declaration);
756                assert scope != null : "Scope is null: " + PsiUtilsKt.getElementTextWithContext(declaration);
757    
758                if (!c.getTopDownAnalysisMode().isLocalDeclarations() && !(bodyResolveCache instanceof BodyResolveCache.ThrowException) &&
759                    expressionTypingServices.getStatementFilter() != StatementFilter.NONE) {
760                    bodyResolveCache.resolveFunctionBody(declaration).addOwnDataTo(trace, true);
761                }
762                else {
763                    resolveFunctionBody(c.getOuterDataFlowInfo(), trace, declaration, entry.getValue(), scope);
764                }
765            }
766        }
767    
768        public void resolveFunctionBody(
769                @NotNull DataFlowInfo outerDataFlowInfo,
770                @NotNull BindingTrace trace,
771                @NotNull KtDeclarationWithBody function,
772                @NotNull FunctionDescriptor functionDescriptor,
773                @NotNull LexicalScope declaringScope
774        ) {
775            computeDeferredType(functionDescriptor.getReturnType());
776    
777            resolveFunctionBody(outerDataFlowInfo, trace, function, functionDescriptor, declaringScope, null, CallChecker.DoNothing.INSTANCE$);
778    
779            assert functionDescriptor.getReturnType() != null;
780        }
781    
782        public void resolveFunctionBody(
783                @NotNull DataFlowInfo outerDataFlowInfo,
784                @NotNull BindingTrace trace,
785                @NotNull KtDeclarationWithBody function,
786                @NotNull FunctionDescriptor functionDescriptor,
787                @NotNull LexicalScope scope,
788                @Nullable Function1<LexicalScope, DataFlowInfo> beforeBlockBody,
789                @NotNull CallChecker callChecker
790        ) {
791            PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace);
792            LexicalScope innerScope = FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace);
793            List<KtParameter> valueParameters = function.getValueParameters();
794            List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
795    
796            valueParameterResolver.resolveValueParameters(
797                    valueParameters, valueParameterDescriptors, innerScope, outerDataFlowInfo, trace, callChecker
798            );
799    
800            // Synthetic "field" creation
801            if (functionDescriptor instanceof PropertyAccessorDescriptor && functionDescriptor.getExtensionReceiverParameter() == null) {
802                PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) functionDescriptor;
803                KtProperty property = (KtProperty) function.getParent();
804                final SyntheticFieldDescriptor fieldDescriptor = new SyntheticFieldDescriptor(accessorDescriptor, property);
805                innerScope = new LexicalScopeImpl(innerScope, functionDescriptor, true, null,
806                                                  LexicalScopeKind.PROPERTY_ACCESSOR_BODY,
807                                                  RedeclarationHandler.DO_NOTHING, new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
808                    @Override
809                    public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
810                        handler.addVariableDescriptor(fieldDescriptor);
811                        return Unit.INSTANCE$;
812                    }
813                });
814                // Check parameter name shadowing
815                for (KtParameter parameter : function.getValueParameters()) {
816                    if (SyntheticFieldDescriptor.NAME.equals(parameter.getNameAsName())) {
817                        trace.report(Errors.ACCESSOR_PARAMETER_NAME_SHADOWING.on(parameter));
818                    }
819                }
820            }
821    
822            DataFlowInfo dataFlowInfo = null;
823    
824            if (beforeBlockBody != null) {
825                dataFlowInfo = beforeBlockBody.invoke(innerScope);
826            }
827    
828            if (function.hasBody()) {
829                expressionTypingServices.checkFunctionReturnType(
830                        innerScope, function, functionDescriptor, dataFlowInfo != null ? dataFlowInfo : outerDataFlowInfo, null, trace);
831            }
832    
833            assert functionDescriptor.getReturnType() != null;
834        }
835    
836        public void resolveConstructorParameterDefaultValuesAndAnnotations(
837                @NotNull DataFlowInfo outerDataFlowInfo,
838                @NotNull BindingTrace trace,
839                @NotNull KtClass klass,
840                @NotNull ConstructorDescriptor constructorDescriptor,
841                @NotNull LexicalScope declaringScope
842        ) {
843            List<KtParameter> valueParameters = klass.getPrimaryConstructorParameters();
844            List<ValueParameterDescriptor> valueParameterDescriptors = constructorDescriptor.getValueParameters();
845    
846            LexicalScope scope = getPrimaryConstructorParametersScope(declaringScope, constructorDescriptor);
847    
848            valueParameterResolver.resolveValueParameters(valueParameters, valueParameterDescriptors, scope, outerDataFlowInfo, trace);
849        }
850    
851        private static void computeDeferredType(KotlinType type) {
852            // handle type inference loop: function or property body contains a reference to itself
853            // fun f() = { f() }
854            // val x = x
855            // type resolution must be started before body resolution
856            if (type instanceof DeferredType) {
857                DeferredType deferredType = (DeferredType) type;
858                if (!deferredType.isComputed()) {
859                    deferredType.getDelegate();
860                }
861            }
862        }
863    
864        private void computeDeferredTypes() {
865            Collection<Box<DeferredType>> deferredTypes = trace.getKeys(DEFERRED_TYPE);
866            if (deferredTypes.isEmpty()) {
867                return;
868            }
869            // +1 is a work around against new Queue(0).addLast(...) bug // stepan.koltsov@ 2011-11-21
870            final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size() + 1);
871            trace.addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
872                @Override
873                public void handleRecord(
874                        WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice,
875                        Box<DeferredType> key,
876                        Boolean value
877                ) {
878                    queue.addLast(key.getData());
879                }
880            });
881            for (Box<DeferredType> deferredType : deferredTypes) {
882                queue.addLast(deferredType.getData());
883            }
884            while (!queue.isEmpty()) {
885                DeferredType deferredType = queue.pullFirst();
886                if (!deferredType.isComputed()) {
887                    try {
888                        deferredType.getDelegate(); // to compute
889                    }
890                    catch (ReenteringLazyValueComputationException e) {
891                        // A problem should be reported while computing the type
892                    }
893                }
894            }
895        }
896    }