Add positioning strategy for diagnostics on illegal fake overrides

"funcitonTypes.kt" test data file was changed because now that there is a
positioning strategy, it takes the liberty of filtering out those diagnostics
that were reported on syntactically invalid elements
This commit is contained in:
Alexander Udalov
2014-04-16 16:44:51 +04:00
parent 146498ec32
commit 1deb55bfde
7 changed files with 31 additions and 32 deletions
@@ -230,10 +230,10 @@ public interface Errors {
DiagnosticFactory2<JetNamedDeclaration, CallableMemberDescriptor, CallableMemberDescriptor> PROPERTY_TYPE_MISMATCH_ON_OVERRIDE =
DiagnosticFactory2.create(ERROR, DECLARATION_RETURN_TYPE);
DiagnosticFactory2<PsiElement, JetClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<PsiElement, JetClassOrObject, CallableMemberDescriptor> MANY_IMPL_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<JetClassOrObject, JetClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR, NAME_IDENTIFIER);
DiagnosticFactory2<JetClassOrObject, JetClassOrObject, CallableMemberDescriptor> MANY_IMPL_MEMBER_NOT_IMPLEMENTED =
DiagnosticFactory2.create(ERROR, NAME_IDENTIFIER);
DiagnosticFactory1<JetNamedDeclaration, Collection<JetType>> AMBIGUOUS_ANONYMOUS_TYPE_INFERRED = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT);
@@ -98,6 +98,9 @@ public class PositioningStrategies {
if (nameIdentifier != null) {
return markElement(nameIdentifier);
}
if (element instanceof JetObjectDeclaration) {
return markElement(((JetObjectDeclaration) element).getObjectKeyword());
}
return markElement(element);
}
};
@@ -157,11 +160,7 @@ public class PositioningStrategies {
nameAsDeclaration.getTextRange().getStartOffset(), primaryConstructorParameterList.getTextRange().getEndOffset()));
}
else if (element instanceof JetObjectDeclaration) {
PsiElement nameAsDeclaration = element.getNameIdentifier();
if (nameAsDeclaration == null) {
return markElement(((JetObjectDeclaration) element).getObjectKeyword());
}
return markRange(nameAsDeclaration.getTextRange());
return NAME_IDENTIFIER.mark(element);
}
return super.mark(element);
}
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -181,16 +180,11 @@ public final class DelegationResolver<T extends CallableMemberDescriptor> {
return false;
}
private boolean checkClashWithOtherDelegatedMember(
@NotNull Collection<T> delegatedMembers,
@NotNull T candidate
) {
private boolean checkClashWithOtherDelegatedMember(@NotNull Collection<T> delegatedMembers, @NotNull T candidate) {
for (CallableMemberDescriptor alreadyDelegatedMember : delegatedMembers) {
if (haveSameSignatures(alreadyDelegatedMember, candidate)) {
//trying to delegate to many traits with the same methods
PsiElement nameIdentifier = classOrObject.getNameIdentifier();
PsiElement element = nameIdentifier != null ? nameIdentifier : classOrObject;
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(element, classOrObject, alreadyDelegatedMember));
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(classOrObject, classOrObject, alreadyDelegatedMember));
return true;
}
}
@@ -326,24 +326,12 @@ public class OverrideResolver {
Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
collectMissingImplementations(classDescriptor, abstractNoImpl, manyImpl);
PsiElement nameIdentifier = null;
if (klass instanceof JetClass) {
nameIdentifier = klass.getNameIdentifier();
}
else if (klass instanceof JetObjectDeclaration) {
nameIdentifier = klass.getNameIdentifier();
if (nameIdentifier == null) {
nameIdentifier = ((JetObjectDeclaration) klass).getObjectKeyword();
}
}
if (nameIdentifier == null) return;
if (!manyImpl.isEmpty()) {
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, manyImpl.iterator().next()));
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, manyImpl.iterator().next()));
}
if (classDescriptor.getModality() != Modality.ABSTRACT && !abstractNoImpl.isEmpty()) {
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, abstractNoImpl.iterator().next()));
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
}
}
@@ -1 +1 @@
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>A<!> : (categoryName: <!SYNTAX!><!>) <!SYNTAX!>{<!SYNTAX!><!><!>
class A : (categoryName: <!SYNTAX!><!>) <!SYNTAX!>{<!SYNTAX!><!><!>
@@ -0,0 +1,13 @@
trait D {
fun foo()
}
trait E {
fun foo() {}
}
object Impl : D, E {
override fun foo() {}
}
val obj: D = <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>object<!> : D by Impl, E by Impl {}
@@ -5429,6 +5429,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest("compiler/testData/diagnostics/tests/override/NonGenerics.kt");
}
@TestMetadata("ObjectDelegationManyImpl.kt")
public void testObjectDelegationManyImpl() throws Exception {
doTest("compiler/testData/diagnostics/tests/override/ObjectDelegationManyImpl.kt");
}
@TestMetadata("OverridingFinalMember.kt")
public void testOverridingFinalMember() throws Exception {
doTest("compiler/testData/diagnostics/tests/override/OverridingFinalMember.kt");