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