Fixing modality in fake overrides

The modality was nondeterministic before.
The main change sits in OverrideResolver: the logic of "fake override" generation is restructured so that
all the descriptors a newly created "fake" one overrides are known by the time it is created, so its
modality can be determined properly from their modalities.

Also, the ReadJavaBinaryClassTestGenerated is now a clear JUnit3 test case
This commit is contained in:
Andrey Breslav
2012-07-06 19:46:43 +04:00
parent 0192e16f39
commit 9f0f6f862a
18 changed files with 152 additions and 120 deletions
@@ -51,5 +51,5 @@ public interface CallableMemberDescriptor extends CallableDescriptor, MemberDesc
Kind getKind();
@NotNull
CallableMemberDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides);
CallableMemberDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides);
}
@@ -108,7 +108,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
@NotNull
@Override
public ConstructorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
public ConstructorDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
throw new UnsupportedOperationException("Constructors should not be copied for overriding");
}
}
@@ -42,5 +42,5 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
@NotNull
@Override
FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides);
FunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides);
}
@@ -20,6 +20,7 @@ package org.jetbrains.jet.lang.descriptors;
* @author abreslav
*/
public enum Modality {
// THE ORDER OF ENTRIES MATTERS HERE
FINAL(false),
OPEN(true),
ABSTRACT(true);
@@ -33,7 +34,7 @@ public enum Modality {
public boolean isOverridable() {
return overridable;
}
public static Modality convertFromFlags(boolean _abstract, boolean open) {
if (_abstract) return ABSTRACT;
if (open) return OPEN;
@@ -123,7 +123,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorNo
@NotNull
@Override
public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
throw new UnsupportedOperationException("Accessors must be copied by the corresponding property");
}
@@ -306,8 +306,8 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
@NotNull
@Override
public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
return doSubstitute(TypeSubstitutor.EMPTY, newOwner, DescriptorUtils.convertModality(modality, makeNonAbstract), makeInvisible ? Visibilities.INVISIBLE_FAKE : visibility, false, copyOverrides, kind);
public PropertyDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
return doSubstitute(TypeSubstitutor.EMPTY, newOwner, modality, makeInvisible ? Visibilities.INVISIBLE_FAKE : visibility, false, copyOverrides, kind);
}
public static PropertyDescriptor createDummy() {
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -50,7 +49,7 @@ public class ScriptCodeDescriptor extends FunctionDescriptorImpl {
@NotNull
@Override
public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
public FunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
throw new IllegalStateException("no need to copy script code descriptor");
}
}
@@ -27,7 +27,7 @@ public interface SimpleFunctionDescriptor extends FunctionDescriptor {
@NotNull
@Override
SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides);
SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides);
@NotNull
@Override
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
@@ -94,9 +93,8 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
@NotNull
@Override
public SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
SimpleFunctionDescriptorImpl copy = (SimpleFunctionDescriptorImpl)doSubstitute(TypeSubstitutor.EMPTY, newOwner, DescriptorUtils
.convertModality(modality, makeNonAbstract), makeInvisible ? Visibilities.INVISIBLE_FAKE : visibility, false, copyOverrides, kind);
public SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
SimpleFunctionDescriptorImpl copy = (SimpleFunctionDescriptorImpl)doSubstitute(TypeSubstitutor.EMPTY, newOwner, modality, makeInvisible ? Visibilities.INVISIBLE_FAKE : visibility, false, copyOverrides, kind);
copy.isInline = isInline;
return copy;
}
@@ -71,7 +71,8 @@ public class DelegationResolver {
if (declarationDescriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor;
if (propertyDescriptor.getModality().isOverridable()) {
PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true, false, CallableMemberDescriptor.Kind.DELEGATION, true);
Modality modality = DescriptorUtils.convertModality(propertyDescriptor.getModality(), true);
PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, modality, false, CallableMemberDescriptor.Kind.DELEGATION, true);
classDescriptor.getBuilder().addPropertyDescriptor(copy);
trace.record(DELEGATED, copy);
}
@@ -79,7 +80,8 @@ public class DelegationResolver {
else if (declarationDescriptor instanceof SimpleFunctionDescriptor) {
SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) declarationDescriptor;
if (functionDescriptor.getModality().isOverridable()) {
SimpleFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true, false, CallableMemberDescriptor.Kind.DELEGATION, true);
Modality modality = DescriptorUtils.convertModality(functionDescriptor.getModality(), true);
SimpleFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, modality, false, CallableMemberDescriptor.Kind.DELEGATION, true);
classDescriptor.getBuilder().addFunctionDescriptor(copy);
trace.record(DELEGATED, copy);
}
@@ -177,45 +177,73 @@ public class OverrideResolver {
public static void generateOverridesInFunctionGroup(
@NotNull Name name,
@NotNull Collection<? extends CallableMemberDescriptor> functionsFromSupertypes,
@NotNull Collection<? extends CallableMemberDescriptor> functionsFromCurrent,
@NotNull Collection<? extends CallableMemberDescriptor> membersFromSupertypes,
@NotNull Collection<? extends CallableMemberDescriptor> membersFromCurrent,
@NotNull ClassDescriptor current,
@NotNull DescriptorSink sink) {
List<CallableMemberDescriptor> fakeOverrideList = Lists.newArrayList();
List<CallableMemberDescriptor> notOverridden = Lists.newArrayList(membersFromSupertypes);
for (CallableMemberDescriptor fromCurrent : membersFromCurrent) {
for (CallableMemberDescriptor functionFromSupertype : functionsFromSupertypes) {
boolean overrides = false;
// Find what this descriptor overrides, bind them and removed from notOverridden
for (Iterator<CallableMemberDescriptor> iterator = notOverridden.iterator(); iterator.hasNext(); ) {
CallableMemberDescriptor fromSupertype = iterator.next();
OverridingUtil.OverrideCompatibilityInfo.Result result =
OverridingUtil.isOverridableBy(fromSupertype, fromCurrent).getResult();
boolean isVisible = Visibilities.isVisible(functionFromSupertype, current);
for (CallableMemberDescriptor functionFromCurrent : functionsFromCurrent) {
OverridingUtil.OverrideCompatibilityInfo.Result result = OverridingUtil.isOverridableBy(functionFromSupertype, functionFromCurrent).getResult();
if (result == OVERRIDABLE) {
if (isVisible) {
OverridingUtil.bindOverride(functionFromCurrent, functionFromSupertype);
if (Visibilities.isVisible(fromSupertype, current)) {
switch (result) {
case OVERRIDABLE:
OverridingUtil.bindOverride(fromCurrent, fromSupertype);
iterator.remove();
break;
case CONFLICT:
sink.conflict(fromSupertype, fromCurrent);
break;
case INCOMPATIBLE:
break;
}
overrides = true;
}
else if (result == OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT) {
sink.conflict(functionFromSupertype, functionFromCurrent);
}
}
for (CallableMemberDescriptor fakeOverride : fakeOverrideList) {
if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).getResult() == OVERRIDABLE) {
OverridingUtil.bindOverride(fakeOverride, functionFromSupertype);
overrides = true;
}
Queue<CallableMemberDescriptor> fromSuperQueue = new LinkedList<CallableMemberDescriptor>(notOverridden);
while (!fromSuperQueue.isEmpty()) {
CallableMemberDescriptor aFromSuper = fromSuperQueue.remove();
Collection<CallableMemberDescriptor> overridableByA = Lists.newArrayList();
overridableByA.add(aFromSuper);
for (Iterator<CallableMemberDescriptor> iterator = fromSuperQueue.iterator(); iterator.hasNext(); ) {
CallableMemberDescriptor bFromSuper = iterator.next();
OverridingUtil.OverrideCompatibilityInfo.Result result =
OverridingUtil.isOverridableBy(bFromSuper, aFromSuper).getResult();
switch (result) {
case OVERRIDABLE:
overridableByA.add(bFromSuper);
iterator.remove();
break;
case CONFLICT:
sink.conflict(aFromSuper, bFromSuper);
iterator.remove();
break;
case INCOMPATIBLE:
break;
}
}
if (!overrides) {
CallableMemberDescriptor fakeOverride = functionFromSupertype.copy(current, false, !isVisible, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
OverridingUtil.bindOverride(fakeOverride, functionFromSupertype);
fakeOverrideList.add(fakeOverride);
sink.addToScope(fakeOverride);
boolean isVisible = true;
Modality modality = Modality.ABSTRACT;
for (CallableMemberDescriptor descriptor : overridableByA) {
isVisible &= Visibilities.isVisible(descriptor, current);
if (descriptor.getModality().compareTo(modality) < 0) {
modality = descriptor.getModality();
}
}
CallableMemberDescriptor fakeOverride =
aFromSuper.copy(current, modality, !isVisible, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
for (CallableMemberDescriptor descriptor : overridableByA) {
OverridingUtil.bindOverride(fakeOverride, descriptor);
}
sink.addToScope(fakeOverride);
}
}
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.Modality;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -40,7 +41,7 @@ public class ExpressionAsFunctionDescriptor extends FunctionDescriptorImpl {
@NotNull
@Override
public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
public FunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
throw new IllegalStateException();
}
}
@@ -45,7 +45,7 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI
@NotNull
@Override
public SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, boolean makeInvisible, Kind kind, boolean copyOverrides) {
public SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, boolean makeInvisible, Kind kind, boolean copyOverrides) {
return this;
}