Get rid of poorly named NotInferredVisibilitySink
Also make TraceBasedErrorReporter invoke OverrideResolver to report "cannot infer visibility", because there's some additional logic there
This commit is contained in:
+2
-9
@@ -17,13 +17,11 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
|
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
||||||
import org.jetbrains.jet.util.slicedmap.Slices;
|
import org.jetbrains.jet.util.slicedmap.Slices;
|
||||||
@@ -31,8 +29,6 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.CANNOT_INFER_VISIBILITY;
|
|
||||||
|
|
||||||
public class TraceBasedErrorReporter implements ErrorReporter {
|
public class TraceBasedErrorReporter implements ErrorReporter {
|
||||||
private static final Logger LOG = Logger.getInstance(TraceBasedErrorReporter.class);
|
private static final Logger LOG = Logger.getInstance(TraceBasedErrorReporter.class);
|
||||||
|
|
||||||
@@ -52,10 +48,7 @@ public class TraceBasedErrorReporter implements ErrorReporter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
public void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor);
|
OverrideResolver.createCannotInferVisibilityReporter(trace).invoke(descriptor);
|
||||||
if (element instanceof JetDeclaration) {
|
|
||||||
trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) element));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+6
-4
@@ -19,6 +19,7 @@ package org.jetbrains.jet.descriptors.serialization.descriptors;
|
|||||||
import kotlin.Function0;
|
import kotlin.Function0;
|
||||||
import kotlin.Function1;
|
import kotlin.Function1;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.descriptors.serialization.*;
|
import org.jetbrains.jet.descriptors.serialization.*;
|
||||||
@@ -280,9 +281,9 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
|
|||||||
OverridingUtil.DescriptorSink sink = new OverridingUtil.DescriptorSink() {
|
OverridingUtil.DescriptorSink sink = new OverridingUtil.DescriptorSink() {
|
||||||
@Override
|
@Override
|
||||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||||
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
|
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new Function1<CallableMemberDescriptor, Unit>() {
|
||||||
@Override
|
@Override
|
||||||
public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
throw new IllegalStateException("Cannot infer visibility for " + descriptor + " in " + classObject);
|
throw new IllegalStateException("Cannot infer visibility for " + descriptor + " in " + classObject);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -433,11 +434,12 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
|
|||||||
new OverridingUtil.DescriptorSink() {
|
new OverridingUtil.DescriptorSink() {
|
||||||
@Override
|
@Override
|
||||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||||
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
|
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new Function1<CallableMemberDescriptor, Unit>() {
|
||||||
@Override
|
@Override
|
||||||
public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
// TODO: do something
|
// TODO: do something
|
||||||
|
return Unit.VALUE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import com.intellij.util.Function;
|
|||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import com.intellij.util.containers.LinkedMultiMap;
|
import com.intellij.util.containers.LinkedMultiMap;
|
||||||
import com.intellij.util.containers.MultiMap;
|
import com.intellij.util.containers.MultiMap;
|
||||||
|
import kotlin.Function1;
|
||||||
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.ReadOnly;
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
@@ -164,16 +166,18 @@ public class OverrideResolver {
|
|||||||
|
|
||||||
public static void resolveUnknownVisibilities(
|
public static void resolveUnknownVisibilities(
|
||||||
@NotNull Collection<? extends CallableMemberDescriptor> descriptors,
|
@NotNull Collection<? extends CallableMemberDescriptor> descriptors,
|
||||||
@NotNull BindingTrace trace) {
|
@NotNull BindingTrace trace
|
||||||
|
) {
|
||||||
for (CallableMemberDescriptor descriptor : descriptors) {
|
for (CallableMemberDescriptor descriptor : descriptors) {
|
||||||
resolveUnknownVisibilityForMember(descriptor, trace);
|
OverridingUtil.resolveUnknownVisibilityForMember(descriptor, createCannotInferVisibilityReporter(trace));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void resolveUnknownVisibilityForMember(@NotNull CallableMemberDescriptor descriptor, @NotNull final BindingTrace trace) {
|
@NotNull
|
||||||
OverridingUtil.resolveUnknownVisibilityForMember(descriptor, new OverridingUtil.NotInferredVisibilitySink() {
|
public static Function1<CallableMemberDescriptor, Unit> createCannotInferVisibilityReporter(@NotNull final BindingTrace trace) {
|
||||||
|
return new Function1<CallableMemberDescriptor, Unit>() {
|
||||||
@Override
|
@Override
|
||||||
public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
DeclarationDescriptor reportOn = descriptor.getKind() == FAKE_OVERRIDE
|
DeclarationDescriptor reportOn = descriptor.getKind() == FAKE_OVERRIDE
|
||||||
? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class)
|
? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class)
|
||||||
: descriptor;
|
: descriptor;
|
||||||
@@ -182,8 +186,9 @@ public class OverrideResolver {
|
|||||||
if (element instanceof JetDeclaration) {
|
if (element instanceof JetDeclaration) {
|
||||||
trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) element));
|
trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) element));
|
||||||
}
|
}
|
||||||
|
return Unit.VALUE;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static enum Filtering {
|
private static enum Filtering {
|
||||||
|
|||||||
+11
-10
@@ -137,11 +137,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
|
public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
|
||||||
// TODO: this should be handled by lazy function descriptors
|
// TODO: this should be handled by lazy function descriptors
|
||||||
Set<FunctionDescriptor> functions = super.getFunctions(name);
|
Set<FunctionDescriptor> functions = super.getFunctions(name);
|
||||||
for (FunctionDescriptor functionDescriptor : functions) {
|
resolveUnknownVisibilitiesForMembers(functions);
|
||||||
if (functionDescriptor.getKind() != FAKE_OVERRIDE && functionDescriptor.getKind() != DELEGATION) {
|
|
||||||
OverrideResolver.resolveUnknownVisibilityForMember(functionDescriptor, trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,17 +202,22 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Set<VariableDescriptor> getProperties(@NotNull Name name) {
|
public Set<VariableDescriptor> getProperties(@NotNull Name name) {
|
||||||
// TODO: this should be handled by lazy property descriptors
|
// TODO: this should be handled by lazy property descriptors
|
||||||
Set<VariableDescriptor> properties = super.getProperties(name);
|
Set<VariableDescriptor> properties = super.getProperties(name);
|
||||||
for (VariableDescriptor variableDescriptor : properties) {
|
resolveUnknownVisibilitiesForMembers((Set) properties);
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
|
|
||||||
if (propertyDescriptor.getKind() == FAKE_OVERRIDE || propertyDescriptor.getKind() == DELEGATION) continue;
|
|
||||||
OverrideResolver.resolveUnknownVisibilityForMember(propertyDescriptor, trace);
|
|
||||||
}
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resolveUnknownVisibilitiesForMembers(@NotNull Set<? extends CallableMemberDescriptor> descriptors) {
|
||||||
|
for (CallableMemberDescriptor descriptor : descriptors) {
|
||||||
|
if (descriptor.getKind() != FAKE_OVERRIDE && descriptor.getKind() != DELEGATION) {
|
||||||
|
OverridingUtil.resolveUnknownVisibilityForMember(descriptor, OverrideResolver.createCannotInferVisibilityReporter(trace));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
|
||||||
|
|||||||
+5
-2
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||||
|
|
||||||
|
import kotlin.Function1;
|
||||||
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -56,10 +58,11 @@ public final class DescriptorResolverUtils {
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||||
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
|
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new Function1<CallableMemberDescriptor, Unit>() {
|
||||||
@Override
|
@Override
|
||||||
public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
errorReporter.reportCannotInferVisibility(descriptor);
|
errorReporter.reportCannotInferVisibility(descriptor);
|
||||||
|
return Unit.VALUE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
result.add((D) fakeOverride);
|
result.add((D) fakeOverride);
|
||||||
|
|||||||
+8
-4
@@ -18,10 +18,10 @@ package org.jetbrains.jet.lang.descriptors.impl;
|
|||||||
|
|
||||||
import kotlin.Function0;
|
import kotlin.Function0;
|
||||||
import kotlin.Function1;
|
import kotlin.Function1;
|
||||||
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
|
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||||
@@ -37,7 +37,10 @@ import org.jetbrains.jet.storage.NotNullLazyValue;
|
|||||||
import org.jetbrains.jet.storage.StorageManager;
|
import org.jetbrains.jet.storage.StorageManager;
|
||||||
import org.jetbrains.jet.utils.Printer;
|
import org.jetbrains.jet.utils.Printer;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
|
public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
|
||||||
private final ClassKind kind;
|
private final ClassKind kind;
|
||||||
@@ -222,10 +225,11 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
|
||||||
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
|
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new Function1<CallableMemberDescriptor, Unit>() {
|
||||||
@Override
|
@Override
|
||||||
public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
|
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
return Unit.VALUE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
result.add((D) fakeOverride);
|
result.add((D) fakeOverride);
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
|
import kotlin.Function1;
|
||||||
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -365,11 +367,11 @@ public class OverridingUtil {
|
|||||||
|
|
||||||
public static void resolveUnknownVisibilityForMember(
|
public static void resolveUnknownVisibilityForMember(
|
||||||
@NotNull CallableMemberDescriptor memberDescriptor,
|
@NotNull CallableMemberDescriptor memberDescriptor,
|
||||||
@NotNull NotInferredVisibilitySink sink
|
@NotNull Function1<CallableMemberDescriptor, Unit> cannotInferVisibility
|
||||||
) {
|
) {
|
||||||
for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
|
for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
|
||||||
if (descriptor.getVisibility() == Visibilities.INHERITED) {
|
if (descriptor.getVisibility() == Visibilities.INHERITED) {
|
||||||
resolveUnknownVisibilityForMember(descriptor, sink);
|
resolveUnknownVisibilityForMember(descriptor, cannotInferVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,11 +379,11 @@ public class OverridingUtil {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Visibility visibilityToInherit = computeVisibilityToInherit(memberDescriptor, sink);
|
Visibility visibilityToInherit = computeVisibilityToInherit(memberDescriptor, cannotInferVisibility);
|
||||||
if (memberDescriptor instanceof PropertyDescriptorImpl) {
|
if (memberDescriptor instanceof PropertyDescriptorImpl) {
|
||||||
((PropertyDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit);
|
((PropertyDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit);
|
||||||
for (PropertyAccessorDescriptor accessor : ((PropertyDescriptor) memberDescriptor).getAccessors()) {
|
for (PropertyAccessorDescriptor accessor : ((PropertyDescriptor) memberDescriptor).getAccessors()) {
|
||||||
resolveUnknownVisibilityForMember(accessor, sink);
|
resolveUnknownVisibilityForMember(accessor, cannotInferVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (memberDescriptor instanceof FunctionDescriptorImpl) {
|
else if (memberDescriptor instanceof FunctionDescriptorImpl) {
|
||||||
@@ -396,11 +398,11 @@ public class OverridingUtil {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private static Visibility computeVisibilityToInherit(
|
private static Visibility computeVisibilityToInherit(
|
||||||
@NotNull CallableMemberDescriptor memberDescriptor,
|
@NotNull CallableMemberDescriptor memberDescriptor,
|
||||||
@NotNull NotInferredVisibilitySink sink
|
@NotNull Function1<CallableMemberDescriptor, Unit> cannotInferVisibility
|
||||||
) {
|
) {
|
||||||
Visibility maxVisibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors());
|
Visibility maxVisibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors());
|
||||||
if (maxVisibility == null) {
|
if (maxVisibility == null) {
|
||||||
sink.cannotInferVisibility(memberDescriptor);
|
cannotInferVisibility.invoke(memberDescriptor);
|
||||||
return Visibilities.PUBLIC;
|
return Visibilities.PUBLIC;
|
||||||
}
|
}
|
||||||
if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||||
@@ -450,10 +452,6 @@ public class OverridingUtil {
|
|||||||
void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent);
|
void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface NotInferredVisibilitySink {
|
|
||||||
void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class OverrideCompatibilityInfo {
|
public static class OverrideCompatibilityInfo {
|
||||||
|
|
||||||
public enum Result {
|
public enum Result {
|
||||||
|
|||||||
Reference in New Issue
Block a user