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