Overriding var by val prohibited
This commit is contained in:
@@ -316,6 +316,7 @@ public interface Errors {
|
||||
}
|
||||
};
|
||||
|
||||
ParameterizedDiagnosticFactory2<PropertyDescriptor, PropertyDescriptor> VAR_OVERRIDDEN_BY_VAL = new ParameterizedDiagnosticFactory2<PropertyDescriptor, PropertyDescriptor>(ERROR, "Var-property {0} cannot be overridden by val-property {1}", DescriptorRenderer.TEXT);
|
||||
|
||||
ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor>(ERROR, "Class ''{0}'' must be declared abstract or implement abstract member {1}") {
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.psi;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -11,6 +12,11 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.JetNodeTypes.PROPERTY_ACCESSOR;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.EQ;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.VAL_KEYWORD;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.VAR_KEYWORD;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
@@ -69,7 +75,7 @@ public class JetProperty extends JetTypeParameterListOwner implements JetModifie
|
||||
|
||||
@NotNull
|
||||
public List<JetPropertyAccessor> getAccessors() {
|
||||
return findChildrenByType(JetNodeTypes.PROPERTY_ACCESSOR);
|
||||
return findChildrenByType(PROPERTY_ACCESSOR);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -92,7 +98,12 @@ public class JetProperty extends JetTypeParameterListOwner implements JetModifie
|
||||
|
||||
@Nullable
|
||||
public JetExpression getInitializer() {
|
||||
PsiElement eq = findChildByType(JetTokens.EQ);
|
||||
PsiElement eq = findChildByType(EQ);
|
||||
return PsiTreeUtil.getNextSiblingOfType(eq, JetExpression.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ASTNode getValOrVarNode() {
|
||||
return getNode().findChildByType(TokenSet.create(VAL_KEYWORD, VAR_KEYWORD));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -105,12 +104,28 @@ public class OverrideResolver {
|
||||
// Check if everything that must be overridden, actually is
|
||||
|
||||
// Everything from supertypes
|
||||
Set<JetType> delegatedByExpression = Sets.newHashSet();
|
||||
for (JetDelegationSpecifier delegationSpecifier : klass.getDelegationSpecifiers()) {
|
||||
if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||
JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier;
|
||||
JetType type = context.getTrace().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
if (type != null) {
|
||||
delegatedByExpression.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<CallableMemberDescriptor, CallableMemberDescriptor> implementedWithDelegationBy = Maps.newHashMap();
|
||||
Set<CallableMemberDescriptor> inheritedFunctions = Sets.newLinkedHashSet();
|
||||
for (JetType supertype : classDescriptor.getSupertypes()) {
|
||||
boolean delegatedBy = delegatedByExpression.contains(supertype);
|
||||
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
|
||||
inheritedFunctions.add(memberDescriptor);
|
||||
if (delegatedBy && memberDescriptor.getModality().isOpen()) {
|
||||
implementedWithDelegationBy.put(memberDescriptor, createOverridingDescriptor(classDescriptor, memberDescriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +138,7 @@ public class OverrideResolver {
|
||||
for (CallableMemberDescriptor one : filteredMembers) {
|
||||
if (factoredMembers.values().contains(one)) continue;
|
||||
for (CallableMemberDescriptor another : filteredMembers) {
|
||||
if (one == another) continue;
|
||||
// if (one == another) continue;
|
||||
factoredMembers.put(one, one);
|
||||
if (OverridingUtil.isOverridableBy(one, another).isSuccess()
|
||||
|| OverridingUtil.isOverridableBy(another, one).isSuccess()) {
|
||||
@@ -154,7 +169,7 @@ public class OverrideResolver {
|
||||
}
|
||||
|
||||
// Members actually present (declared) in the class
|
||||
Set<CallableDescriptor> actuallyOverridden = Sets.newHashSet();
|
||||
Set<CallableMemberDescriptor> actuallyOverridden = Sets.newHashSet(implementedWithDelegationBy.keySet());
|
||||
for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
|
||||
actuallyOverridden.addAll(member.getOverriddenDescriptors());
|
||||
}
|
||||
@@ -215,6 +230,11 @@ public class OverrideResolver {
|
||||
// }
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CallableMemberDescriptor createOverridingDescriptor(@NotNull MutableClassDescriptor subClass, @NotNull CallableMemberDescriptor superDescriptor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkOverride(CallableMemberDescriptor declared) {
|
||||
JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declared);
|
||||
assert member != null;
|
||||
@@ -224,6 +244,7 @@ public class OverrideResolver {
|
||||
|
||||
boolean finalOverriddenError = false;
|
||||
boolean typeMismatchError = false;
|
||||
boolean kindMismatchError = false;
|
||||
for (CallableMemberDescriptor overridden : declared.getOverriddenDescriptors()) {
|
||||
if (overridden != null) {
|
||||
if (hasOverrideModifier) {
|
||||
@@ -237,6 +258,11 @@ public class OverrideResolver {
|
||||
context.getTrace().report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
|
||||
typeMismatchError = true;
|
||||
}
|
||||
|
||||
if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false) && !kindMismatchError) {
|
||||
context.getTrace().report(VAR_OVERRIDDEN_BY_VAL.on(member, ((JetProperty) member).getValOrVarNode(), (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
|
||||
typeMismatchError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,4 +279,12 @@ public class OverrideResolver {
|
||||
context.getTrace().report(VIRTUAL_MEMBER_HIDDEN.on(member, nameIdentifier, declared, overridden, overridden.getContainingDeclaration()));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkPropertyKind(CallableMemberDescriptor descriptor, boolean isVar) {
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
return propertyDescriptor.isVar() == isVar;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
open class Var() {
|
||||
open var v : Int = 1
|
||||
}
|
||||
|
||||
class Val() : Var() {
|
||||
override <!VAR_OVERRIDDEN_BY_VAL!>val<!> v : Int = 1
|
||||
}
|
||||
|
||||
class Var2() : Var() {
|
||||
override var v : Int = 1
|
||||
}
|
||||
Reference in New Issue
Block a user