Postpone force resolve of annotations on properties

Otherwise (after subsequent commits) we may end up calling
BindingContext.HAS_BACKING_FIELD too early and getting incorrect value,
which will influence which annotations the property and the field will
have, and since they're cached as soon as they're computed, they will
remain incorrect until the end of the program. Now we're calling force
resolve after bodies of property accessors are resolved, which is the
point where the backing field presence has been already determined for
certain.

This all still looks very fragile because we might try to get property's
annotations anywhere else before the accessors' bodies are analyzed, but
I have no idea at the moment how to improve this without refactoring the
whole subsystem
This commit is contained in:
Alexander Udalov
2018-08-09 19:15:21 +02:00
parent 8d44824875
commit 6fb39785ff
2 changed files with 10 additions and 9 deletions
@@ -742,6 +742,8 @@ public class BodyResolver {
}
resolvePropertyAccessors(c, property, propertyDescriptor);
ForceResolveUtil.forceResolveAllContents(propertyDescriptor.getAnnotations());
}
private void resolvePropertyDeclarationBodies(@NotNull BodiesResolveContext c) {
@@ -797,28 +799,28 @@ public class BodyResolver {
languageVersionSettings.supportsFeature(LanguageFeature.ProhibitErroneousExpressionsInAnnotationsWithUseSiteTargets);
if (getterDescriptor != null) {
if (getter != null || forceResolveAnnotations) {
ForceResolveUtil.forceResolveAllContents(getterDescriptor.getAnnotations());
}
if (getter != null) {
LexicalScope accessorScope = makeScopeForPropertyAccessor(c, getter, propertyDescriptor);
resolveFunctionBody(c.getOuterDataFlowInfo(), fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope);
}
if (getter != null || forceResolveAnnotations) {
ForceResolveUtil.forceResolveAllContents(getterDescriptor.getAnnotations());
}
}
KtPropertyAccessor setter = property.getSetter();
PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
if (setterDescriptor != null) {
if (setter != null || forceResolveAnnotations) {
ForceResolveUtil.forceResolveAllContents(setterDescriptor.getAnnotations());
}
if (setter != null) {
LexicalScope accessorScope = makeScopeForPropertyAccessor(c, setter, propertyDescriptor);
resolveFunctionBody(c.getOuterDataFlowInfo(), fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope);
}
if (setter != null || forceResolveAnnotations) {
ForceResolveUtil.forceResolveAllContents(setterDescriptor.getAnnotations());
}
}
}
@@ -273,7 +273,6 @@ class LazyTopDownAnalyzer(
val descriptor = lazyDeclarationResolver.resolveToDescriptor(property) as PropertyDescriptor
c.properties.put(property, descriptor)
ForceResolveUtil.forceResolveAllContents(descriptor.annotations)
registerTopLevelFqName(topLevelFqNames, property, descriptor)
}
}