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