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