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