001    /*
002     * Copyright 2010-2016 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.FunctionTypesKt;
028    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
029    import org.jetbrains.kotlin.descriptors.*;
030    import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
031    import org.jetbrains.kotlin.diagnostics.Errors;
032    import org.jetbrains.kotlin.lexer.KtTokens;
033    import org.jetbrains.kotlin.psi.*;
034    import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
035    import org.jetbrains.kotlin.resolve.calls.CallResolver;
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.types.*;
043    import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
044    import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor;
045    import org.jetbrains.kotlin.types.expressions.ValueParameterResolver;
046    import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
047    import org.jetbrains.kotlin.util.Box;
048    import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
049    import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
050    
051    import java.util.*;
052    
053    import static org.jetbrains.kotlin.diagnostics.Errors.*;
054    import static org.jetbrains.kotlin.resolve.BindingContext.*;
055    import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
056    
057    public class BodyResolver {
058        @NotNull private final AnnotationChecker annotationChecker;
059        @NotNull private final ExpressionTypingServices expressionTypingServices;
060        @NotNull private final CallResolver callResolver;
061        @NotNull private final ObservableBindingTrace trace;
062        @NotNull private final ControlFlowAnalyzer controlFlowAnalyzer;
063        @NotNull private final DeclarationsChecker declarationsChecker;
064        @NotNull private final AnnotationResolver annotationResolver;
065        @NotNull private final DelegatedPropertyResolver delegatedPropertyResolver;
066        @NotNull private final FunctionAnalyzerExtension functionAnalyzerExtension;
067        @NotNull private final ValueParameterResolver valueParameterResolver;
068        @NotNull private final BodyResolveCache bodyResolveCache;
069        @NotNull private final KotlinBuiltIns builtIns;
070    
071        public BodyResolver(
072                @NotNull AnnotationResolver annotationResolver,
073                @NotNull BodyResolveCache bodyResolveCache,
074                @NotNull CallResolver callResolver,
075                @NotNull ControlFlowAnalyzer controlFlowAnalyzer,
076                @NotNull DeclarationsChecker declarationsChecker,
077                @NotNull DelegatedPropertyResolver delegatedPropertyResolver,
078                @NotNull ExpressionTypingServices expressionTypingServices,
079                @NotNull FunctionAnalyzerExtension functionAnalyzerExtension,
080                @NotNull BindingTrace trace,
081                @NotNull ValueParameterResolver valueParameterResolver,
082                @NotNull AnnotationChecker annotationChecker,
083                @NotNull KotlinBuiltIns builtIns
084        ) {
085            this.annotationResolver = annotationResolver;
086            this.bodyResolveCache = bodyResolveCache;
087            this.callResolver = callResolver;
088            this.controlFlowAnalyzer = controlFlowAnalyzer;
089            this.declarationsChecker = declarationsChecker;
090            this.delegatedPropertyResolver = delegatedPropertyResolver;
091            this.expressionTypingServices = expressionTypingServices;
092            this.functionAnalyzerExtension = functionAnalyzerExtension;
093            this.annotationChecker = annotationChecker;
094            this.trace = new ObservableBindingTrace(trace);
095            this.valueParameterResolver = valueParameterResolver;
096            this.builtIns = builtIns;
097        }
098    
099        private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext c) {
100            resolveSuperTypeEntryLists(c);
101    
102            resolvePropertyDeclarationBodies(c);
103    
104            resolveAnonymousInitializers(c);
105            resolvePrimaryConstructorParameters(c);
106            resolveSecondaryConstructors(c);
107    
108            resolveFunctionBodies(c);
109    
110            if (!c.getTopDownAnalysisMode().isLocalDeclarations()) {
111                computeDeferredTypes();
112            }
113        }
114    
115        private void resolveSecondaryConstructors(@NotNull BodiesResolveContext c) {
116            for (Map.Entry<KtSecondaryConstructor, ConstructorDescriptor> entry : c.getSecondaryConstructors().entrySet()) {
117                LexicalScope declaringScope = c.getDeclaringScope(entry.getKey());
118                assert declaringScope != null : "Declaring scope should be registered before body resolve";
119                resolveSecondaryConstructorBody(c.getOuterDataFlowInfo(), trace, entry.getKey(), entry.getValue(), declaringScope);
120            }
121            if (c.getSecondaryConstructors().isEmpty()) return;
122            Set<ConstructorDescriptor> visitedConstructors = Sets.newHashSet();
123            for (Map.Entry<KtSecondaryConstructor, ConstructorDescriptor> entry : c.getSecondaryConstructors().entrySet()) {
124                checkCyclicConstructorDelegationCall(entry.getValue(), visitedConstructors);
125            }
126        }
127    
128        public void resolveSecondaryConstructorBody(
129                @NotNull final DataFlowInfo outerDataFlowInfo,
130                @NotNull final BindingTrace trace,
131                @NotNull final KtSecondaryConstructor constructor,
132                @NotNull final ConstructorDescriptor descriptor,
133                @NotNull LexicalScope declaringScope
134        ) {
135            ForceResolveUtil.forceResolveAllContents(descriptor.getAnnotations());
136    
137            resolveFunctionBody(outerDataFlowInfo, trace, constructor, descriptor, declaringScope,
138                                new Function1<LexicalScope, DataFlowInfo>() {
139                                    @Override
140                                    public DataFlowInfo invoke(@NotNull LexicalScope headerInnerScope) {
141                                        return resolveSecondaryConstructorDelegationCall(outerDataFlowInfo, trace, headerInnerScope,
142                                                                                         constructor, descriptor);
143                                    }
144                                },
145                                new Function1<LexicalScope, LexicalScope>() {
146                                    @Override
147                                    public LexicalScope invoke(LexicalScope scope) {
148                                        return new LexicalScopeImpl(
149                                                scope, descriptor, scope.isOwnerDescriptorAccessibleByLabel(), scope.getImplicitReceiver(),
150                                                LexicalScopeKind.CONSTRUCTOR_HEADER);
151                                    }
152                                });
153        }
154    
155        @Nullable
156        private DataFlowInfo resolveSecondaryConstructorDelegationCall(
157                @NotNull DataFlowInfo outerDataFlowInfo,
158                @NotNull BindingTrace trace,
159                @NotNull LexicalScope scope,
160                @NotNull KtSecondaryConstructor constructor,
161                @NotNull ConstructorDescriptor descriptor
162        ) {
163            OverloadResolutionResults<?> results = callResolver.resolveConstructorDelegationCall(
164                    trace, scope, outerDataFlowInfo,
165                    descriptor, constructor.getDelegationCall());
166    
167            if (results != null && results.isSingleResult()) {
168                ResolvedCall<? extends CallableDescriptor> resolvedCall = results.getResultingCall();
169                recordConstructorDelegationCall(trace, descriptor, resolvedCall);
170                return resolvedCall.getDataFlowInfoForArguments().getResultInfo();
171            }
172            return null;
173        }
174    
175        private void checkCyclicConstructorDelegationCall(
176                @NotNull ConstructorDescriptor constructorDescriptor,
177                @NotNull Set<ConstructorDescriptor> visitedConstructors
178        ) {
179            if (visitedConstructors.contains(constructorDescriptor)) return;
180    
181            // if visit constructor that is already in current chain
182            // such constructor is on cycle
183            Set<ConstructorDescriptor> visitedInCurrentChain = Sets.newHashSet();
184            ConstructorDescriptor currentConstructorDescriptor = constructorDescriptor;
185            while (true) {
186                visitedInCurrentChain.add(currentConstructorDescriptor);
187                ConstructorDescriptor delegatedConstructorDescriptor = getDelegatedConstructor(currentConstructorDescriptor);
188                if (delegatedConstructorDescriptor == null) break;
189    
190                // if next delegation call is super or primary constructor or already visited
191                if (!constructorDescriptor.getContainingDeclaration().equals(delegatedConstructorDescriptor.getContainingDeclaration()) ||
192                    delegatedConstructorDescriptor.isPrimary() ||
193                    visitedConstructors.contains(delegatedConstructorDescriptor)) {
194                    break;
195                }
196    
197                if (visitedInCurrentChain.contains(delegatedConstructorDescriptor)) {
198                    reportEachConstructorOnCycle(delegatedConstructorDescriptor);
199                    break;
200                }
201                currentConstructorDescriptor = delegatedConstructorDescriptor;
202            }
203            visitedConstructors.addAll(visitedInCurrentChain);
204        }
205    
206        private void reportEachConstructorOnCycle(@NotNull ConstructorDescriptor startConstructor) {
207            ConstructorDescriptor currentConstructor = startConstructor;
208            do {
209                PsiElement constructorToReport = DescriptorToSourceUtils.descriptorToDeclaration(currentConstructor);
210                if (constructorToReport != null) {
211                    KtConstructorDelegationCall call = ((KtSecondaryConstructor) constructorToReport).getDelegationCall();
212                    assert call.getCalleeExpression() != null
213                            : "Callee expression of delegation call should not be null on cycle as there should be explicit 'this' calls";
214                    trace.report(CYCLIC_CONSTRUCTOR_DELEGATION_CALL.on(call.getCalleeExpression()));
215                }
216    
217                currentConstructor = getDelegatedConstructor(currentConstructor);
218                assert currentConstructor != null : "Delegated constructor should not be null in cycle";
219            }
220            while (startConstructor != currentConstructor);
221        }
222    
223        @Nullable
224        private ConstructorDescriptor getDelegatedConstructor(@NotNull ConstructorDescriptor constructor) {
225            ResolvedCall<ConstructorDescriptor> call = trace.get(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor);
226            return call == null || !call.getStatus().isSuccess() ? null : call.getResultingDescriptor().getOriginal();
227        }
228    
229        public void resolveBodies(@NotNull BodiesResolveContext c) {
230            resolveBehaviorDeclarationBodies(c);
231            controlFlowAnalyzer.process(c);
232            declarationsChecker.process(c);
233            functionAnalyzerExtension.process(c);
234        }
235    
236        private void resolveSuperTypeEntryLists(@NotNull BodiesResolveContext c) {
237            // TODO : Make sure the same thing is not initialized twice
238            for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
239                KtClassOrObject classOrObject = entry.getKey();
240                ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
241    
242                resolveSuperTypeEntryList(c.getOuterDataFlowInfo(), classOrObject, descriptor,
243                                          descriptor.getUnsubstitutedPrimaryConstructor(),
244                                          descriptor.getScopeForConstructorHeaderResolution(),
245                                          descriptor.getScopeForMemberDeclarationResolution());
246            }
247        }
248    
249        public void resolveSuperTypeEntryList(
250                @NotNull final DataFlowInfo outerDataFlowInfo,
251                @NotNull KtClassOrObject jetClass,
252                @NotNull final ClassDescriptor descriptor,
253                @Nullable final ConstructorDescriptor primaryConstructor,
254                @NotNull LexicalScope scopeForConstructorResolution,
255                @NotNull final LexicalScope scopeForMemberResolution
256        ) {
257            final LexicalScope scopeForConstructor =
258                    primaryConstructor == null
259                    ? null
260                    : FunctionDescriptorUtil.getFunctionInnerScope(scopeForConstructorResolution, primaryConstructor, trace);
261            final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
262    
263            final Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap();
264            final ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1];
265            KtVisitorVoid visitor = new KtVisitorVoid() {
266                private void recordSupertype(KtTypeReference typeReference, KotlinType supertype) {
267                    if (supertype == null) return;
268                    supertypes.put(typeReference, supertype);
269                }
270    
271                @Override
272                public void visitDelegatedSuperTypeEntry(@NotNull KtDelegatedSuperTypeEntry specifier) {
273                    if (descriptor.getKind() == ClassKind.INTERFACE) {
274                        trace.report(DELEGATION_IN_INTERFACE.on(specifier));
275                    }
276                    KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
277                    recordSupertype(specifier.getTypeReference(), supertype);
278                    if (supertype != null) {
279                        DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
280                        if (declarationDescriptor instanceof ClassDescriptor) {
281                            ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
282                            if (classDescriptor.getKind() != ClassKind.INTERFACE) {
283                                trace.report(DELEGATION_NOT_TO_INTERFACE.on(specifier.getTypeReference()));
284                            }
285                        }
286                    }
287                    KtExpression delegateExpression = specifier.getDelegateExpression();
288                    if (delegateExpression != null) {
289                        LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
290                        KotlinType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE;
291                        typeInferrer.getType(scope, delegateExpression, expectedType, outerDataFlowInfo, trace);
292                    }
293                    if (primaryConstructor == null) {
294                        trace.report(UNSUPPORTED.on(specifier, "Delegation without primary constructor is not supported"));
295                    }
296                }
297    
298                @Override
299                public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
300                    KtValueArgumentList valueArgumentList = call.getValueArgumentList();
301                    PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList;
302                    if (descriptor.getKind() == ClassKind.INTERFACE) {
303                        trace.report(SUPERTYPE_INITIALIZED_IN_INTERFACE.on(elementToMark));
304                    }
305                    KtTypeReference typeReference = call.getTypeReference();
306                    if (typeReference == null) return;
307                    if (primaryConstructor == null) {
308                        if (descriptor.getKind() != ClassKind.INTERFACE) {
309                            trace.report(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR.on(call));
310                        }
311                        recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
312                        return;
313                    }
314                    OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
315                            trace, scopeForConstructor,
316                            CallMaker.makeConstructorCallWithoutTypeArguments(call), NO_EXPECTED_TYPE, outerDataFlowInfo, false);
317                    if (results.isSuccess()) {
318                        KotlinType supertype = results.getResultingDescriptor().getReturnType();
319                        recordSupertype(typeReference, supertype);
320                        ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
321                        if (classDescriptor != null) {
322                            // allow only one delegating constructor
323                            if (primaryConstructorDelegationCall[0] == null) {
324                                primaryConstructorDelegationCall[0] = results.getResultingCall();
325                            }
326                            else {
327                                primaryConstructorDelegationCall[0] = null;
328                            }
329                        }
330                        // Recording type info for callee to use later in JetObjectLiteralExpression
331                        trace.record(PROCESSED, call.getCalleeExpression(), true);
332                        trace.record(EXPRESSION_TYPE_INFO, call.getCalleeExpression(),
333                                     TypeInfoFactoryKt.noTypeInfo(results.getResultingCall().getDataFlowInfoForArguments().getResultInfo()));
334                    }
335                    else {
336                        recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
337                    }
338                }
339    
340                @Override
341                public void visitSuperTypeEntry(@NotNull KtSuperTypeEntry specifier) {
342                    KtTypeReference typeReference = specifier.getTypeReference();
343                    KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
344                    recordSupertype(typeReference, supertype);
345                    if (supertype == null) return;
346                    ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype);
347                    if (superClass == null) return;
348                    if (superClass.getKind().isSingleton()) {
349                        // A "singleton in supertype" diagnostic will be reported later
350                        return;
351                    }
352                    if (descriptor.getKind() != ClassKind.INTERFACE &&
353                        descriptor.getUnsubstitutedPrimaryConstructor() != null &&
354                        superClass.getKind() != ClassKind.INTERFACE &&
355                        !superClass.getConstructors().isEmpty() &&
356                        !ErrorUtils.isError(superClass)
357                    ) {
358                        trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
359                    }
360                }
361    
362                @Override
363                public void visitKtElement(@NotNull KtElement element) {
364                    throw new UnsupportedOperationException(element.getText() + " : " + element);
365                }
366            };
367    
368            for (KtSuperTypeListEntry delegationSpecifier : jetClass.getSuperTypeListEntries()) {
369                delegationSpecifier.accept(visitor);
370            }
371    
372            if (DescriptorUtils.isAnnotationClass(descriptor) && jetClass.getSuperTypeList() != null) {
373                trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(jetClass.getSuperTypeList()));
374            }
375    
376            if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
377                recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]);
378            }
379    
380            checkSupertypeList(descriptor, supertypes, jetClass);
381        }
382    
383        // Returns a set of enum or sealed types of which supertypeOwner is an entry or a member
384        @NotNull
385        private static Set<TypeConstructor> getAllowedFinalSupertypes(
386                @NotNull ClassDescriptor descriptor,
387                @NotNull KtClassOrObject jetClass
388        ) {
389            Set<TypeConstructor> parentEnumOrSealed;
390            if (jetClass instanceof KtEnumEntry) {
391                parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor());
392            }
393            else {
394                parentEnumOrSealed = Collections.emptySet();
395                ClassDescriptor currentDescriptor = descriptor;
396                while (currentDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
397                    currentDescriptor = (ClassDescriptor) currentDescriptor.getContainingDeclaration();
398                    if (currentDescriptor.getModality() == Modality.SEALED) {
399                        if (parentEnumOrSealed.isEmpty()) {
400                            parentEnumOrSealed = new HashSet<TypeConstructor>();
401                        }
402                        parentEnumOrSealed.add(currentDescriptor.getTypeConstructor());
403                    }
404                }
405            }
406            return parentEnumOrSealed;
407        }
408    
409        private static void recordConstructorDelegationCall(
410                @NotNull BindingTrace trace,
411                @NotNull ConstructorDescriptor constructor,
412                @NotNull ResolvedCall<?> call
413        ) {
414            //noinspection unchecked
415            trace.record(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor, (ResolvedCall<ConstructorDescriptor>) call);
416        }
417    
418        private void checkSupertypeList(
419                @NotNull ClassDescriptor supertypeOwner,
420                @NotNull Map<KtTypeReference, KotlinType> supertypes,
421                @NotNull KtClassOrObject jetClass
422        ) {
423            Set<TypeConstructor> allowedFinalSupertypes = getAllowedFinalSupertypes(supertypeOwner, jetClass);
424            Set<TypeConstructor> typeConstructors = Sets.newHashSet();
425            boolean classAppeared = false;
426            for (Map.Entry<KtTypeReference, KotlinType> entry : supertypes.entrySet()) {
427                KtTypeReference typeReference = entry.getKey();
428                KotlinType supertype = entry.getValue();
429    
430                KtTypeElement typeElement = typeReference.getTypeElement();
431                if (typeElement instanceof KtFunctionType) {
432                    for (KtParameter parameter : ((KtFunctionType) typeElement).getParameters()) {
433                        PsiElement nameIdentifier = parameter.getNameIdentifier();
434    
435                        if (nameIdentifier != null) {
436                            trace.report(Errors.UNSUPPORTED.on(nameIdentifier, "named parameter in function type in supertype position"));
437                        }
438                    }
439                }
440    
441                boolean addSupertype = true;
442    
443                ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
444                if (classDescriptor != null) {
445                    if (ErrorUtils.isError(classDescriptor)) continue;
446    
447                    if (FunctionTypesKt.isExtensionFunctionType(supertype)) {
448                        trace.report(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE.on(typeReference));
449                    }
450    
451                    if (classDescriptor.getKind() != ClassKind.INTERFACE) {
452                        if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) {
453                            trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference));
454                            addSupertype = false;
455                        }
456                        else if (supertypeOwner.getKind() == ClassKind.INTERFACE &&
457                                 !classAppeared && !DynamicTypesKt.isDynamic(supertype) /* avoid duplicate diagnostics */) {
458                            trace.report(INTERFACE_WITH_SUPERCLASS.on(typeReference));
459                            addSupertype = false;
460                        }
461                        else if (jetClass.hasModifier(KtTokens.DATA_KEYWORD)) {
462                            trace.report(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES.on(typeReference));
463                            addSupertype = false;
464                        }
465                        else if (DescriptorUtils.isSubclass(classDescriptor, builtIns.getThrowable()) &&
466                                 !supertypeOwner.getDeclaredTypeParameters().isEmpty()) {
467                            trace.report(GENERIC_THROWABLE_SUBCLASS.on(jetClass.getTypeParameterList()));
468                            addSupertype = false;
469                        }
470    
471                        if (classAppeared) {
472                            trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference));
473                        }
474                        else {
475                            classAppeared = true;
476                        }
477                    }
478                }
479                else {
480                    trace.report(SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.on(typeReference));
481                }
482    
483                TypeConstructor constructor = supertype.getConstructor();
484                if (addSupertype && !typeConstructors.add(constructor)) {
485                    trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
486                }
487    
488                if (classDescriptor == null) return;
489                if (classDescriptor.getKind().isSingleton()) {
490                    if (!DescriptorUtils.isEnumEntry(classDescriptor)) {
491                        trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
492                    }
493                }
494                else if (!allowedFinalSupertypes.contains(constructor)) {
495                    if (classDescriptor.getModality() == Modality.SEALED) {
496                        DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration();
497                        while (containingDescriptor != null && containingDescriptor != classDescriptor) {
498                            containingDescriptor = containingDescriptor.getContainingDeclaration();
499                        }
500                        if (containingDescriptor == null) {
501                            trace.report(SEALED_SUPERTYPE.on(typeReference));
502                        }
503                        else {
504                            trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference));
505                        }
506                    }
507                    else if (ModalityKt.isFinalOrEnum(classDescriptor)) {
508                        trace.report(FINAL_SUPERTYPE.on(typeReference));
509                    }
510                }
511            }
512        }
513    
514        private void resolveAnonymousInitializers(@NotNull BodiesResolveContext c) {
515            for (Map.Entry<KtAnonymousInitializer, ClassDescriptorWithResolutionScopes> entry : c.getAnonymousInitializers().entrySet()) {
516                KtAnonymousInitializer initializer = entry.getKey();
517                ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
518                resolveAnonymousInitializer(c.getOuterDataFlowInfo(), initializer, descriptor);
519            }
520        }
521    
522        public void resolveAnonymousInitializer(
523                @NotNull DataFlowInfo outerDataFlowInfo,
524                @NotNull KtAnonymousInitializer anonymousInitializer,
525                @NotNull ClassDescriptorWithResolutionScopes classDescriptor
526        ) {
527            LexicalScope scopeForInitializers = classDescriptor.getScopeForInitializerResolution();
528            KtExpression body = anonymousInitializer.getBody();
529            if (body != null) {
530                PreliminaryDeclarationVisitor.Companion.createForDeclaration(
531                        (KtDeclaration) anonymousInitializer.getParent().getParent(), trace);
532                expressionTypingServices.getTypeInfo(
533                        scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace, /*isStatement = */true
534                );
535            }
536            processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
537            if (classDescriptor.getConstructors().isEmpty()) {
538                trace.report(ANONYMOUS_INITIALIZER_IN_INTERFACE.on(anonymousInitializer));
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.getScopeForConstructorHeaderResolution(),
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, LocalRedeclarationChecker.DO_NOTHING.INSTANCE,
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 = ScopeUtils.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 = ScopeUtils.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 = ScopeUtils.makeScopeForDelegateConventionFunctions(propertyHeaderScope, propertyDescriptor);
710    
711            LexicalScope initializerScope = ScopeUtils.makeScopeForPropertyInitializer(propertyHeaderScope, propertyDescriptor);
712    
713            KotlinType delegateType = delegatedPropertyResolver.resolveDelegateExpression(
714                    delegateExpression, property, propertyDescriptor, initializerScope, trace,
715                    outerDataFlowInfo);
716    
717            delegatedPropertyResolver.resolveDelegatedPropertyGetMethod(
718                    propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo
719            );
720    
721            if (property.isVar()) {
722                delegatedPropertyResolver.resolveDelegatedPropertySetMethod(
723                        propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo
724                );
725            }
726    
727            delegatedPropertyResolver.resolveDelegatedPropertyPDMethod(
728                    propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo
729            );
730        }
731    
732        private void resolvePropertyInitializer(
733                @NotNull DataFlowInfo outerDataFlowInfo,
734                @NotNull KtProperty property,
735                @NotNull PropertyDescriptor propertyDescriptor,
736                @NotNull KtExpression initializer,
737                @NotNull LexicalScope propertyHeader
738        ) {
739            LexicalScope propertyDeclarationInnerScope = ScopeUtils.makeScopeForPropertyInitializer(propertyHeader, propertyDescriptor);
740            KotlinType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
741            if (propertyDescriptor.getCompileTimeInitializer() == null) {
742                expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer,
743                                                 outerDataFlowInfo, trace);
744            }
745        }
746    
747        @NotNull
748        private static LexicalScope getScopeForProperty(@NotNull BodiesResolveContext c, @NotNull KtProperty property) {
749            LexicalScope scope = c.getDeclaringScope(property);
750            assert scope != null : "Scope for property " + property.getText() + " should exists";
751            return scope;
752        }
753    
754        private void resolveFunctionBodies(@NotNull BodiesResolveContext c) {
755            for (Map.Entry<KtNamedFunction, SimpleFunctionDescriptor> entry : c.getFunctions().entrySet()) {
756                KtNamedFunction declaration = entry.getKey();
757    
758                LexicalScope scope = c.getDeclaringScope(declaration);
759                assert scope != null : "Scope is null: " + PsiUtilsKt.getElementTextWithContext(declaration);
760    
761                if (!c.getTopDownAnalysisMode().isLocalDeclarations() && !(bodyResolveCache instanceof BodyResolveCache.ThrowException) &&
762                    expressionTypingServices.getStatementFilter() != StatementFilter.NONE) {
763                    bodyResolveCache.resolveFunctionBody(declaration).addOwnDataTo(trace, true);
764                }
765                else {
766                    resolveFunctionBody(c.getOuterDataFlowInfo(), trace, declaration, entry.getValue(), scope);
767                }
768            }
769        }
770    
771        public void resolveFunctionBody(
772                @NotNull DataFlowInfo outerDataFlowInfo,
773                @NotNull BindingTrace trace,
774                @NotNull KtDeclarationWithBody function,
775                @NotNull FunctionDescriptor functionDescriptor,
776                @NotNull LexicalScope declaringScope
777        ) {
778            computeDeferredType(functionDescriptor.getReturnType());
779    
780            resolveFunctionBody(outerDataFlowInfo, trace, function, functionDescriptor, declaringScope, null, null);
781    
782            assert functionDescriptor.getReturnType() != null;
783        }
784    
785        private void resolveFunctionBody(
786                @NotNull DataFlowInfo outerDataFlowInfo,
787                @NotNull BindingTrace trace,
788                @NotNull KtDeclarationWithBody function,
789                @NotNull FunctionDescriptor functionDescriptor,
790                @NotNull LexicalScope scope,
791                @Nullable Function1<LexicalScope, DataFlowInfo> beforeBlockBody,
792                // Creates wrapper scope for header resolution if necessary (see resolveSecondaryConstructorBody)
793                @Nullable Function1<LexicalScope, LexicalScope> headerScopeFactory
794        ) {
795            PreliminaryDeclarationVisitor.Companion.createForDeclaration(function, trace);
796            LexicalScope innerScope = FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace);
797            List<KtParameter> valueParameters = function.getValueParameters();
798            List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
799    
800            LexicalScope headerScope = headerScopeFactory != null ? headerScopeFactory.invoke(innerScope) : innerScope;
801            valueParameterResolver.resolveValueParameters(
802                    valueParameters, valueParameterDescriptors, headerScope, outerDataFlowInfo, trace
803            );
804    
805            // Synthetic "field" creation
806            if (functionDescriptor instanceof PropertyAccessorDescriptor && functionDescriptor.getExtensionReceiverParameter() == null) {
807                PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) functionDescriptor;
808                KtProperty property = (KtProperty) function.getParent();
809                final SyntheticFieldDescriptor fieldDescriptor = new SyntheticFieldDescriptor(accessorDescriptor, property);
810                innerScope = new LexicalScopeImpl(innerScope, functionDescriptor, true, null,
811                                                  LexicalScopeKind.PROPERTY_ACCESSOR_BODY,
812                                                  LocalRedeclarationChecker.DO_NOTHING.INSTANCE, new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
813                    @Override
814                    public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
815                        handler.addVariableDescriptor(fieldDescriptor);
816                        return Unit.INSTANCE;
817                    }
818                });
819                // Check parameter name shadowing
820                for (KtParameter parameter : function.getValueParameters()) {
821                    if (SyntheticFieldDescriptor.NAME.equals(parameter.getNameAsName())) {
822                        trace.report(Errors.ACCESSOR_PARAMETER_NAME_SHADOWING.on(parameter));
823                    }
824                }
825            }
826    
827            DataFlowInfo dataFlowInfo = null;
828    
829            if (beforeBlockBody != null) {
830                dataFlowInfo = beforeBlockBody.invoke(headerScope);
831            }
832    
833            if (function.hasBody()) {
834                expressionTypingServices.checkFunctionReturnType(
835                        innerScope, function, functionDescriptor, dataFlowInfo != null ? dataFlowInfo : outerDataFlowInfo, null, trace);
836            }
837    
838            assert functionDescriptor.getReturnType() != null;
839        }
840    
841        public void resolveConstructorParameterDefaultValuesAndAnnotations(
842                @NotNull DataFlowInfo outerDataFlowInfo,
843                @NotNull BindingTrace trace,
844                @NotNull KtClass klass,
845                @NotNull ConstructorDescriptor constructorDescriptor,
846                @NotNull LexicalScope declaringScope
847        ) {
848            List<KtParameter> valueParameters = klass.getPrimaryConstructorParameters();
849            List<ValueParameterDescriptor> valueParameterDescriptors = constructorDescriptor.getValueParameters();
850    
851            LexicalScope scope = getPrimaryConstructorParametersScope(declaringScope, constructorDescriptor);
852    
853            valueParameterResolver.resolveValueParameters(valueParameters, valueParameterDescriptors, scope, outerDataFlowInfo, trace);
854        }
855    
856        private static void computeDeferredType(KotlinType type) {
857            // handle type inference loop: function or property body contains a reference to itself
858            // fun f() = { f() }
859            // val x = x
860            // type resolution must be started before body resolution
861            if (type instanceof DeferredType) {
862                DeferredType deferredType = (DeferredType) type;
863                if (!deferredType.isComputed()) {
864                    deferredType.getDelegate();
865                }
866            }
867        }
868    
869        private void computeDeferredTypes() {
870            Collection<Box<DeferredType>> deferredTypes = trace.getKeys(DEFERRED_TYPE);
871            if (deferredTypes.isEmpty()) {
872                return;
873            }
874            // +1 is a work around against new Queue(0).addLast(...) bug // stepan.koltsov@ 2011-11-21
875            final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size() + 1);
876            trace.addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
877                @Override
878                public void handleRecord(
879                        WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice,
880                        Box<DeferredType> key,
881                        Boolean value
882                ) {
883                    queue.addLast(key.getData());
884                }
885            });
886            for (Box<DeferredType> deferredType : deferredTypes) {
887                queue.addLast(deferredType.getData());
888            }
889            while (!queue.isEmpty()) {
890                DeferredType deferredType = queue.pullFirst();
891                if (!deferredType.isComputed()) {
892                    try {
893                        deferredType.getDelegate(); // to compute
894                    }
895                    catch (ReenteringLazyValueComputationException e) {
896                        // A problem should be reported while computing the type
897                    }
898                }
899            }
900        }
901    }