More override control.
Renderers in errors. Constructor parameters are not properties unless otherwise specified
This commit is contained in:
+2
-1
@@ -144,7 +144,8 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassDescriptor substitute(TypeSubstitutor substitutor) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
if (substitutor.isEmpty()) return this;
|
||||
return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.create(substitutor.getSubstitution(), getSubstitutor().getSubstitution()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-6
@@ -23,8 +23,9 @@ import java.util.*;
|
||||
public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike {
|
||||
private ConstructorDescriptor primaryConstructor;
|
||||
private final Set<FunctionDescriptor> constructors = Sets.newLinkedHashSet();
|
||||
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
|
||||
private final Set<CallableMemberDescriptor> callableMembers = Sets.newHashSet();
|
||||
private final Set<PropertyDescriptor> properties = Sets.newHashSet();
|
||||
private final Set<FunctionDescriptor> functions = Sets.newHashSet();
|
||||
private List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
|
||||
private Collection<JetType> supertypes = Lists.newArrayList();
|
||||
|
||||
@@ -95,18 +96,15 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
@Override
|
||||
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
properties.add(propertyDescriptor);
|
||||
callableMembers.add(propertyDescriptor);
|
||||
scopeForMemberLookup.addVariableDescriptor(propertyDescriptor);
|
||||
scopeForMemberResolution.addVariableDescriptor(propertyDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<PropertyDescriptor> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
functions.add(functionDescriptor);
|
||||
callableMembers.add(functionDescriptor);
|
||||
scopeForMemberLookup.addFunctionDescriptor(functionDescriptor);
|
||||
scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
|
||||
}
|
||||
@@ -116,6 +114,16 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
return functions;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<PropertyDescriptor> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<CallableMemberDescriptor> getCallableMembers() {
|
||||
return callableMembers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceDescriptorImpl getNamespace(String name) {
|
||||
throw new UnsupportedOperationException("Classes do not define namespaces");
|
||||
|
||||
+7
-1
@@ -5,12 +5,18 @@ import java.text.MessageFormat;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class DiagnosticFactoryWithMessageFormat extends DiagnosticFactoryWithSeverity {
|
||||
public abstract class DiagnosticFactoryWithMessageFormat extends DiagnosticFactoryWithSeverity {
|
||||
protected final MessageFormat messageFormat;
|
||||
protected final Renderer renderer;
|
||||
|
||||
public DiagnosticFactoryWithMessageFormat(Severity severity, String message) {
|
||||
this(severity, message, Renderer.TO_STRING);
|
||||
}
|
||||
|
||||
public DiagnosticFactoryWithMessageFormat(Severity severity, String message, Renderer renderer) {
|
||||
super(severity);
|
||||
this.messageFormat = new MessageFormat(message);
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-1
@@ -9,6 +9,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author svtk
|
||||
*/
|
||||
public abstract class DiagnosticFactoryWithPsiElement1<T extends PsiElement, A> extends DiagnosticFactoryWithMessageFormat {
|
||||
|
||||
protected DiagnosticFactoryWithPsiElement1(Severity severity, String message, Renderer renderer) {
|
||||
super(severity, message, renderer);
|
||||
}
|
||||
|
||||
protected DiagnosticFactoryWithPsiElement1(Severity severity, String message) {
|
||||
super(severity, message);
|
||||
}
|
||||
@@ -18,7 +23,7 @@ public abstract class DiagnosticFactoryWithPsiElement1<T extends PsiElement, A>
|
||||
}
|
||||
|
||||
protected String makeMessageFor(A argument) {
|
||||
return argument.toString();
|
||||
return renderer.render(argument);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+8
-4
@@ -9,8 +9,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author abreslav
|
||||
*/
|
||||
public abstract class DiagnosticFactoryWithPsiElement2<T extends PsiElement, A, B> extends DiagnosticFactoryWithMessageFormat {
|
||||
|
||||
public DiagnosticFactoryWithPsiElement2(Severity severity, String message) {
|
||||
|
||||
protected DiagnosticFactoryWithPsiElement2(Severity severity, String message, Renderer renderer) {
|
||||
super(severity, message, renderer);
|
||||
}
|
||||
|
||||
protected DiagnosticFactoryWithPsiElement2(Severity severity, String message) {
|
||||
super(severity, message);
|
||||
}
|
||||
|
||||
@@ -19,11 +23,11 @@ public abstract class DiagnosticFactoryWithPsiElement2<T extends PsiElement, A,
|
||||
}
|
||||
|
||||
protected String makeMessageForA(@NotNull A a) {
|
||||
return a.toString();
|
||||
return renderer.render(a);
|
||||
}
|
||||
|
||||
protected String makeMessageForB(@NotNull B b) {
|
||||
return b.toString();
|
||||
return renderer.render(b);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+10
-6
@@ -8,9 +8,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class DiagnosticFactoryWithPsiElement3<T extends PsiElement, A, B, C> extends DiagnosticFactoryWithMessageFormat {
|
||||
protected DiagnosticFactoryWithPsiElement3(Severity severity, String messageStub) {
|
||||
super(severity, messageStub);
|
||||
public abstract class DiagnosticFactoryWithPsiElement3<T extends PsiElement, A, B, C> extends DiagnosticFactoryWithMessageFormat {
|
||||
protected DiagnosticFactoryWithPsiElement3(Severity severity, String messageStub, Renderer renderer) {
|
||||
super(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
protected DiagnosticFactoryWithPsiElement3(Severity severity, String message) {
|
||||
super(severity, message);
|
||||
}
|
||||
|
||||
protected String makeMessage(@NotNull A a, @NotNull B b, @NotNull C c) {
|
||||
@@ -18,15 +22,15 @@ public class DiagnosticFactoryWithPsiElement3<T extends PsiElement, A, B, C> ext
|
||||
}
|
||||
|
||||
protected String makeMessageForA(@NotNull A a) {
|
||||
return a.toString();
|
||||
return renderer.render(a);
|
||||
}
|
||||
|
||||
protected String makeMessageForB(@NotNull B b) {
|
||||
return b.toString();
|
||||
return renderer.render(b);
|
||||
}
|
||||
|
||||
protected String makeMessageForC(@NotNull C c) {
|
||||
return c.toString();
|
||||
return renderer.render(c);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.diagnostics;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class DiagnosticFactoryWithSeverity extends AbstractDiagnosticFactory {
|
||||
public abstract class DiagnosticFactoryWithSeverity extends AbstractDiagnosticFactory {
|
||||
protected final Severity severity;
|
||||
|
||||
public DiagnosticFactoryWithSeverity(Severity severity) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
@@ -23,6 +24,24 @@ import static org.jetbrains.jet.lang.diagnostics.Severity.WARNING;
|
||||
*/
|
||||
public interface Errors {
|
||||
|
||||
Renderer NAME = new Renderer() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String render(@Nullable Object object) {
|
||||
if (object == null) return "null";
|
||||
if (object instanceof Named) {
|
||||
return ((Named) object).getName();
|
||||
}
|
||||
return object.toString();
|
||||
}
|
||||
};
|
||||
|
||||
ParameterizedDiagnosticFactory1<Throwable> EXCEPTION_WHILE_ANALYZING = new ParameterizedDiagnosticFactory1<Throwable>(ERROR, "{0}") {
|
||||
@Override
|
||||
protected String makeMessageFor(@NotNull Throwable e) {
|
||||
return e.getClass().getSimpleName() + ": " + e.getMessage();
|
||||
}
|
||||
};
|
||||
UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = UnresolvedReferenceDiagnosticFactory.INSTANCE;
|
||||
RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.INSTANCE;
|
||||
PsiElementOnlyDiagnosticFactory2<PsiElement, JetType, JetType> TYPE_MISMATCH = PsiElementOnlyDiagnosticFactory2.create(ERROR, "Type mismatch: inferred type is {1} but {0} was expected");
|
||||
@@ -40,6 +59,7 @@ public interface Errors {
|
||||
return sb.toString();
|
||||
}
|
||||
};
|
||||
|
||||
PsiElementOnlyDiagnosticFactory2<JetModifierList, JetKeywordToken, JetKeywordToken> REDUNDANT_MODIFIER = new PsiElementOnlyDiagnosticFactory2<JetModifierList, JetKeywordToken, JetKeywordToken>(Severity.WARNING, "Modifier {0} is redundant because {1} is present") {
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -47,26 +67,25 @@ public interface Errors {
|
||||
return new DiagnosticWithAdditionalInfo<JetModifierList, JetKeywordToken>(this, severity, makeMessage(redundantModifier, presentModifier), element, node.getTextRange(), redundantModifier);
|
||||
}
|
||||
};
|
||||
|
||||
SimpleDiagnosticFactory SAFE_CALLS_ARE_NOT_ALLOWED_ON_NAMESPACES = SimpleDiagnosticFactory.create(ERROR, "Safe calls are not allowed on namespaces");
|
||||
SimpleDiagnosticFactory TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM = SimpleDiagnosticFactory.create(ERROR, "Type checking has run into a recursive problem"); // TODO: message
|
||||
SimpleDiagnosticFactory RETURN_NOT_ALLOWED = SimpleDiagnosticFactory.create(ERROR, "'return' is not allowed here");
|
||||
SimpleDiagnosticFactory PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "Projections are not allowed for immediate arguments of a supertype");
|
||||
SimpleDiagnosticFactory LABEL_NAME_CLASH = SimpleDiagnosticFactory.create(WARNING, "There is more than one label with such a name in this scope");
|
||||
SimpleDiagnosticFactory EXPRESSION_EXPECTED_NAMESPACE_FOUND = SimpleDiagnosticFactory.create(ERROR, "Expression expected, but a namespace name found");
|
||||
|
||||
SimpleDiagnosticFactory CANNOT_INFER_PARAMETER_TYPE = SimpleDiagnosticFactory.create(ERROR, "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation");
|
||||
|
||||
SimpleDiagnosticFactory NO_BACKING_FIELD = SimpleDiagnosticFactory.create(ERROR, "This property does not have a backing field");
|
||||
|
||||
SimpleDiagnosticFactory MIXING_NAMED_AND_POSITIONED_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Mixing named and positioned arguments in not allowed");
|
||||
SimpleDiagnosticFactory ARGUMENT_PASSED_TWICE = SimpleDiagnosticFactory.create(ERROR, "An argument is already passed for this parameter");
|
||||
SimpleDiagnosticFactory NAMED_PARAMETER_NOT_FOUND = SimpleDiagnosticFactory.create(ERROR, "Cannot find a parameter with this name");
|
||||
SimpleDiagnosticFactory VARARG_OUTSIDE_PARENTHESES = SimpleDiagnosticFactory.create(ERROR, "Passing value as a vararg is only allowed inside a parenthesized argument list");
|
||||
|
||||
SimpleDiagnosticFactory MANY_FUNCTION_LITERAL_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Only one function literal is allowed outside a parenthesized argument list");
|
||||
|
||||
SimpleDiagnosticFactory PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = SimpleDiagnosticFactory.create(ERROR, "This property must either have a type annotation or be initialized");
|
||||
SimpleDiagnosticFactory FUNCTION_WITH_NO_TYPE_NO_BODY = SimpleDiagnosticFactory.create(ERROR, "This function must either declare a return type or have a body element");
|
||||
|
||||
SimpleDiagnosticFactory FUNCTION_WITH_NO_TYPE_NO_BODY = SimpleDiagnosticFactory.create(ERROR, "This function must either declare a return type or have a body element");
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "This property cannot be declared abstract");
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_NOT_IN_CLASS = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "A property may be abstract only when defined in a class or trait");
|
||||
//TODO pass String instead of JetType or ensure JetType's value is computed
|
||||
@@ -96,17 +115,17 @@ public interface Errors {
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunctionOrPropertyAccessor, FunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract");
|
||||
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, FunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} is not a class or trait member and cannot be abstract");
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetModifierListOwner> NON_MEMBER_ABSTRACT_ACCESSOR = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "This property is not a class or trait member and thus cannot have abstract accessors"); // TODO : Better message
|
||||
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunctionOrPropertyAccessor, FunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} must have a body");
|
||||
|
||||
SimpleDiagnosticFactory PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = SimpleDiagnosticFactory.create(ERROR, "Projections are not allowed on type arguments of functions and properties"); // TODO : better positioning
|
||||
|
||||
SimpleDiagnosticFactory SUPERTYPE_NOT_INITIALIZED = SimpleDiagnosticFactory.create(ERROR, "This type has a constructor, and thus must be initialized here");
|
||||
SimpleDiagnosticFactory SECONDARY_CONSTRUCTOR_BUT_NO_PRIMARY = SimpleDiagnosticFactory.create(ERROR, "A secondary constructor may appear only in a class that has a primary constructor");
|
||||
SimpleDiagnosticFactory SECONDARY_CONSTRUCTOR_NO_INITIALIZER_LIST = SimpleDiagnosticFactory.create(ERROR, "Secondary constructors must have an initializer list");
|
||||
SimpleDiagnosticFactory BY_IN_SECONDARY_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "'by'-clause is only supported for primary constructors");
|
||||
SimpleDiagnosticFactory INITIALIZER_WITH_NO_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Constructor arguments required");
|
||||
SimpleDiagnosticFactory MANY_CALLS_TO_THIS = SimpleDiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed");
|
||||
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "{0} overrides nothing");
|
||||
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "{0} overrides nothing", DescriptorRenderer.TEXT);
|
||||
ParameterizedDiagnosticFactory1<PropertyDescriptor> PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY = ParameterizedDiagnosticFactory1.create(ERROR, "This class must have a primary constructor, because property {0} has a backing field");
|
||||
ParameterizedDiagnosticFactory1<JetClassOrObject> PRIMARY_CONSTRUCTOR_MISSING_SUPER_CONSTRUCTOR_CALL = new ParameterizedDiagnosticFactory1<JetClassOrObject>(ERROR, "Class {0} must have a constructor in order to be able to initialize supertypes") {
|
||||
@Override
|
||||
@@ -114,13 +133,7 @@ public interface Errors {
|
||||
return JetPsiUtil.safeName(argument.getName());
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory1<Throwable> EXCEPTION_WHILE_ANALYZING = new ParameterizedDiagnosticFactory1<Throwable>(ERROR, "{0}") {
|
||||
@Override
|
||||
protected String makeMessageFor(@NotNull Throwable e) {
|
||||
return e.getClass().getSimpleName() + ": " + e.getMessage();
|
||||
}
|
||||
};
|
||||
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier");
|
||||
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
|
||||
|
||||
SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code");
|
||||
ParameterizedDiagnosticFactory1<String> UNREACHABLE_BECAUSE_OF_NOTHING = ParameterizedDiagnosticFactory1.create(ERROR, "This code is unreachable, because ''{0}'' never terminates normally");
|
||||
@@ -151,13 +164,7 @@ public interface Errors {
|
||||
SimpleDiagnosticFactory CAST_NEVER_SUCCEEDS = SimpleDiagnosticFactory.create(WARNING, "This cast can never succeed");
|
||||
DiagnosticWithAdditionalInfoFactory1<JetPropertyAccessor, JetType> WRONG_SETTER_PARAMETER_TYPE = DiagnosticWithAdditionalInfoFactory1.create(ERROR, "Setter parameter type must be equal to the type of the property, i.e. {0}");
|
||||
DiagnosticWithAdditionalInfoFactory1<JetPropertyAccessor, JetType> WRONG_GETTER_RETURN_TYPE = DiagnosticWithAdditionalInfoFactory1.create(ERROR, "Getter return type must be equal to the type of the property, i.e. {0}");
|
||||
ParameterizedDiagnosticFactory1<ClassifierDescriptor> NO_CLASS_OBJECT = new ParameterizedDiagnosticFactory1<ClassifierDescriptor>(ERROR, "Classifier {0} does not have a class object") {
|
||||
@Override
|
||||
protected String makeMessageFor(@NotNull ClassifierDescriptor argument) {
|
||||
return argument.getName();
|
||||
}
|
||||
};
|
||||
|
||||
ParameterizedDiagnosticFactory1<ClassifierDescriptor> NO_CLASS_OBJECT = ParameterizedDiagnosticFactory1.create(ERROR, "Classifier {0} does not have a class object", NAME);
|
||||
SimpleDiagnosticFactory NO_GENERICS_IN_SUPERTYPE_SPECIFIER = SimpleDiagnosticFactory.create(ERROR, "Generic arguments of the base type must be specified");
|
||||
|
||||
SimpleDiagnosticFactory HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY = SimpleDiagnosticFactory.create(ERROR, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property");
|
||||
@@ -187,12 +194,7 @@ public interface Errors {
|
||||
return argument.getName();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory1<TypeParameterDescriptor> CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS = new ParameterizedDiagnosticFactory1<TypeParameterDescriptor>(ERROR, "Class object upper bounds of {0} have empty intersection") {
|
||||
@Override
|
||||
protected String makeMessageFor(@NotNull TypeParameterDescriptor argument) {
|
||||
return argument.getName();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory1<TypeParameterDescriptor> CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS = ParameterizedDiagnosticFactory1.create(ERROR, "Class object upper bounds of {0} have empty intersection", NAME);
|
||||
|
||||
ParameterizedDiagnosticFactory1<CallableDescriptor> TOO_MANY_ARGUMENTS = ParameterizedDiagnosticFactory1.create(ERROR, "Too many arguments for {0}");
|
||||
ParameterizedDiagnosticFactory1<String> ERROR_COMPILE_TIME_VALUE = ParameterizedDiagnosticFactory1.create(ERROR, "{0}");
|
||||
@@ -229,12 +231,7 @@ public interface Errors {
|
||||
return constraintOwner.getName();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory2<JetType, VariableDescriptor> AUTOCAST_IMPOSSIBLE = new ParameterizedDiagnosticFactory2<JetType, VariableDescriptor>(ERROR, "Automatic cast to {0} is impossible, because variable {1} is mutable") {
|
||||
@Override
|
||||
protected String makeMessageForB(@NotNull VariableDescriptor variableDescriptor) {
|
||||
return variableDescriptor.getName();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory2<JetType, VariableDescriptor> AUTOCAST_IMPOSSIBLE = ParameterizedDiagnosticFactory2.create(ERROR, "Automatic cast to {0} is impossible, because variable {1} is mutable", NAME);
|
||||
|
||||
ParameterizedDiagnosticFactory2<JetType, JetType> TYPE_MISMATCH_IN_FOR_LOOP = ParameterizedDiagnosticFactory2.create(ERROR, "The loop iterates over values of type {0} but the parameter is declared to be {1}");
|
||||
ParameterizedDiagnosticFactory1<JetType> TYPE_MISMATCH_IN_CONDITION = ParameterizedDiagnosticFactory1.create(ERROR, "Condition must be of type Boolean, but was of type {0}");
|
||||
@@ -273,32 +270,73 @@ public interface Errors {
|
||||
return nameExpression.getReferencedName();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory2<CallableMemberDescriptor, DeclarationDescriptor> OVERRIDING_FINAL_MEMBER = new ParameterizedDiagnosticFactory2<CallableMemberDescriptor, DeclarationDescriptor>(ERROR, "{0} in {1} is final and cannot be overridden") {
|
||||
ParameterizedDiagnosticFactory2<CallableMemberDescriptor, DeclarationDescriptor> OVERRIDING_FINAL_MEMBER = ParameterizedDiagnosticFactory2.create(ERROR, "{0} in {1} is final and cannot be overridden", NAME);
|
||||
|
||||
ParameterizedDiagnosticFactory2<CallableMemberDescriptor, CallableMemberDescriptor> RETURN_TYPE_MISMATCH_ON_OVERRIDE = new ParameterizedDiagnosticFactory2<CallableMemberDescriptor, CallableMemberDescriptor>(ERROR, "Return type of {0} is not a subtype of the return type overridden member {1}") {
|
||||
@NotNull
|
||||
@Override
|
||||
protected String makeMessageForA(@NotNull CallableMemberDescriptor functionDescriptor) {
|
||||
return functionDescriptor.getName();
|
||||
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
|
||||
PsiElement psiElement = ((DiagnosticWithPsiElement) diagnostic).getPsiElement();
|
||||
JetTypeReference returnTypeRef = null;
|
||||
ASTNode nameNode = null;
|
||||
if (psiElement instanceof JetNamedFunction) {
|
||||
JetFunction function = (JetNamedFunction) psiElement;
|
||||
returnTypeRef = function.getReturnTypeRef();
|
||||
nameNode = getNameNode(function);
|
||||
}
|
||||
else if (psiElement instanceof JetProperty) {
|
||||
JetProperty property = (JetProperty) psiElement;
|
||||
returnTypeRef = property.getPropertyTypeRef();
|
||||
nameNode = getNameNode(property);
|
||||
}
|
||||
else if (psiElement instanceof JetPropertyAccessor) {
|
||||
JetPropertyAccessor accessor = (JetPropertyAccessor) psiElement;
|
||||
returnTypeRef = accessor.getReturnTypeReference();
|
||||
nameNode = accessor.getNamePlaceholder().getNode();
|
||||
}
|
||||
if (returnTypeRef != null) return returnTypeRef.getTextRange();
|
||||
if (nameNode != null) return nameNode.getTextRange();
|
||||
return super.getTextRange(diagnostic);
|
||||
}
|
||||
|
||||
private ASTNode getNameNode(JetNamedDeclaration function) {
|
||||
PsiElement nameIdentifier = function.getNameIdentifier();
|
||||
return nameIdentifier == null ? null : nameIdentifier.getNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeMessageForB(@NotNull DeclarationDescriptor descriptor) {
|
||||
return descriptor.getName();
|
||||
protected String makeMessageForA(@NotNull CallableMemberDescriptor callableMemberDescriptor) {
|
||||
return DescriptorRenderer.TEXT.render(callableMemberDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeMessageForB(@NotNull CallableMemberDescriptor callableMemberDescriptor) {
|
||||
return DescriptorRenderer.TEXT.render(callableMemberDescriptor);
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory3<JetClassOrObject, FunctionDescriptor, DeclarationDescriptor> ABSTRACT_METHOD_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory3<JetClassOrObject, FunctionDescriptor, DeclarationDescriptor>(ERROR, "Class ''{0}'' must be declared abstract or implement abstract method ''{1}'' declared in {2}") {
|
||||
|
||||
|
||||
ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor>(ERROR, "Class ''{0}'' must be declared abstract or implement abstract member {1}") {
|
||||
@Override
|
||||
protected String makeMessageForA(@NotNull JetClassOrObject jetClassOrObject) {
|
||||
return jetClassOrObject.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeMessageForB(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
return DescriptorRenderer.TEXT.render(functionDescriptor);
|
||||
protected String makeMessageForB(@NotNull CallableMemberDescriptor memberDescriptor) {
|
||||
return DescriptorRenderer.TEXT.render(memberDescriptor);
|
||||
}
|
||||
};
|
||||
|
||||
ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor> MANY_IMPL_MEMBER_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor>(ERROR, "Class ''{0}'' must override {1} because it inherits many implementations of it") {
|
||||
@Override
|
||||
protected String makeMessageForA(@NotNull JetClassOrObject jetClassOrObject) {
|
||||
return jetClassOrObject.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeMessageForC(@NotNull DeclarationDescriptor descriptor) {
|
||||
return descriptor.getName();
|
||||
protected String makeMessageForB(@NotNull CallableMemberDescriptor memberDescriptor) {
|
||||
return DescriptorRenderer.TEXT.render(memberDescriptor);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -344,4 +382,5 @@ public interface Errors {
|
||||
private static final Initializer INSTANCE = new Initializer();
|
||||
private Initializer() {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-2
@@ -14,8 +14,16 @@ public class ParameterizedDiagnosticFactory1<A> extends DiagnosticFactoryWithPsi
|
||||
return new ParameterizedDiagnosticFactory1<T>(severity, messageStub);
|
||||
}
|
||||
|
||||
protected ParameterizedDiagnosticFactory1(Severity severity, String messageStub) {
|
||||
super(severity, messageStub);
|
||||
public static <T> ParameterizedDiagnosticFactory1<T> create(Severity severity, String messageStub, Renderer renderer) {
|
||||
return new ParameterizedDiagnosticFactory1<T>(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
public ParameterizedDiagnosticFactory1(Severity severity, String message, Renderer renderer) {
|
||||
super(severity, message, renderer);
|
||||
}
|
||||
|
||||
public ParameterizedDiagnosticFactory1(Severity severity, String message) {
|
||||
super(severity, message);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+8
@@ -14,6 +14,14 @@ public class ParameterizedDiagnosticFactory2<A, B> extends DiagnosticFactoryWith
|
||||
return new ParameterizedDiagnosticFactory2<A, B>(severity, messageStub);
|
||||
}
|
||||
|
||||
public static <A, B> ParameterizedDiagnosticFactory2<A, B> create(Severity severity, String messageStub, Renderer renderer) {
|
||||
return new ParameterizedDiagnosticFactory2<A, B>(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
public ParameterizedDiagnosticFactory2(Severity severity, String message, Renderer renderer) {
|
||||
super(severity, message, renderer);
|
||||
}
|
||||
|
||||
public ParameterizedDiagnosticFactory2(Severity severity, String messageStub) {
|
||||
super(severity, messageStub);
|
||||
}
|
||||
|
||||
+8
@@ -14,6 +14,14 @@ public class ParameterizedDiagnosticFactory3<A, B, C> extends DiagnosticFactoryW
|
||||
return new ParameterizedDiagnosticFactory3<A, B, C>(severity, messageStub);
|
||||
}
|
||||
|
||||
public static <A, B, C> ParameterizedDiagnosticFactory3<A, B, C> create(Severity severity, String messageStub, Renderer renderer) {
|
||||
return new ParameterizedDiagnosticFactory3<A, B, C>(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
public ParameterizedDiagnosticFactory3(Severity severity, String messageStub, Renderer renderer) {
|
||||
super(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
protected ParameterizedDiagnosticFactory3(Severity severity, String messageStub) {
|
||||
super(severity, messageStub);
|
||||
}
|
||||
|
||||
+9
-1
@@ -8,7 +8,15 @@ public class PsiElementOnlyDiagnosticFactory1<T extends PsiElement, A> extends D
|
||||
public static <T extends PsiElement, A> PsiElementOnlyDiagnosticFactory1<T, A> create(Severity severity, String messageStub) {
|
||||
return new PsiElementOnlyDiagnosticFactory1<T, A>(severity, messageStub);
|
||||
}
|
||||
|
||||
|
||||
public static <T extends PsiElement, A> PsiElementOnlyDiagnosticFactory1<T, A> create(Severity severity, String messageStub, Renderer renderer) {
|
||||
return new PsiElementOnlyDiagnosticFactory1<T, A>(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
public PsiElementOnlyDiagnosticFactory1(Severity severity, String message, Renderer renderer) {
|
||||
super(severity, message, renderer);
|
||||
}
|
||||
|
||||
protected PsiElementOnlyDiagnosticFactory1(Severity severity, String message) {
|
||||
super(severity, message);
|
||||
}
|
||||
|
||||
+10
-2
@@ -5,11 +5,19 @@ import com.intellij.psi.PsiElement;
|
||||
* @author svtk
|
||||
*/
|
||||
public class PsiElementOnlyDiagnosticFactory3<T extends PsiElement, A, B, C> extends DiagnosticFactoryWithPsiElement3<T, A, B, C> implements PsiElementOnlyDiagnosticFactory<T> {
|
||||
public static <T extends PsiElement, A, B, C> PsiElementOnlyDiagnosticFactory3<T, A, B, C> create(Severity severity, String messageStub) {
|
||||
return new PsiElementOnlyDiagnosticFactory3<T, A, B, C>(severity, messageStub);
|
||||
}
|
||||
|
||||
public static <T extends PsiElement, A, B, C> PsiElementOnlyDiagnosticFactory3<T, A, B, C> create(Severity severity, String messageStub, Renderer renderer) {
|
||||
return new PsiElementOnlyDiagnosticFactory3<T, A, B, C>(severity, messageStub, renderer);
|
||||
}
|
||||
|
||||
protected PsiElementOnlyDiagnosticFactory3(Severity severity, String messageStub) {
|
||||
super(severity, messageStub);
|
||||
}
|
||||
|
||||
public static <T extends PsiElement, A, B, C> PsiElementOnlyDiagnosticFactory3<T, A, B, C> create(Severity severity, String messageStub) {
|
||||
return new PsiElementOnlyDiagnosticFactory3<T, A, B, C>(severity, messageStub);
|
||||
public PsiElementOnlyDiagnosticFactory3(Severity severity, String messageStub, Renderer renderer) {
|
||||
super(severity, messageStub, renderer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.jetbrains.jet.lang.diagnostics;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface Renderer {
|
||||
Renderer TO_STRING = new Renderer() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String render(@Nullable Object object) {
|
||||
return object == null ? "null" : object.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TO_STRING";
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
String render(@Nullable Object object);
|
||||
}
|
||||
@@ -1483,7 +1483,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
myBuilder.disableNewlines();
|
||||
expect(LPAR, "Expecting '(", recoverySet);
|
||||
|
||||
if (!at(RPAR)) {
|
||||
if (!at(RPAR) && !atSet(recoverySet)) {
|
||||
while (true) {
|
||||
if (at(COMMA)) {
|
||||
errorAndAdvance("Expecting a parameter declaration");
|
||||
|
||||
@@ -71,6 +71,7 @@ public class JetPropertyAccessor extends JetDeclaration implements JetFunctionOr
|
||||
return findChildByClass(JetTypeReference.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getNamePlaceholder() {
|
||||
PsiElement get = findChildByType(JetTokens.GET_KEYWORD);
|
||||
if (get != null) {
|
||||
|
||||
@@ -525,7 +525,10 @@ public class ClassDescriptorResolver {
|
||||
final JetExpression initializer = property.getInitializer();
|
||||
if (initializer == null) {
|
||||
// trace.getErrorHandler().genericError(property.getNode(), "This property must either have a type annotation or be initialized");
|
||||
trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(property));
|
||||
PsiElement nameIdentifier = property.getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(nameIdentifier.getNode()));
|
||||
}
|
||||
return ErrorUtils.createErrorType("No type, no body");
|
||||
} else {
|
||||
// TODO : a risk of a memory leak
|
||||
|
||||
@@ -139,13 +139,15 @@ public class DeclarationResolver {
|
||||
JetScope memberScope = classDescriptor.getScopeForSupertypeResolution();
|
||||
ConstructorDescriptor constructorDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass);
|
||||
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
||||
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorParameterToAProperty(
|
||||
classDescriptor,
|
||||
memberScope,
|
||||
parameter
|
||||
);
|
||||
classDescriptor.addPropertyDescriptor(propertyDescriptor);
|
||||
context.getPrimaryConstructorParameterProperties().add(propertyDescriptor);
|
||||
if (parameter.getValOrVarNode() != null) {
|
||||
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolvePrimaryConstructorParameterToAProperty(
|
||||
classDescriptor,
|
||||
memberScope,
|
||||
parameter
|
||||
);
|
||||
classDescriptor.addPropertyDescriptor(propertyDescriptor);
|
||||
context.getPrimaryConstructorParameterProperties().add(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
if (constructorDescriptor != null) {
|
||||
classDescriptor.setPrimaryConstructor(constructorDescriptor);
|
||||
|
||||
@@ -68,7 +68,7 @@ public class OverrideResolver {
|
||||
private FunctionDescriptor findFunctionOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) {
|
||||
Set<FunctionDescriptor> functionGroup = supertype.getMemberScope().getFunctions(declaredFunction.getName());
|
||||
for (FunctionDescriptor functionDescriptor : functionGroup) {
|
||||
if (OverridingUtil.isOverridableBy(context.getSemanticServices().getTypeChecker(), functionDescriptor, declaredFunction).isSuccess()) {
|
||||
if (OverridingUtil.isOverridableBy(functionDescriptor, declaredFunction).isSuccess()) {
|
||||
return functionDescriptor;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class OverrideResolver {
|
||||
if (property == null) {
|
||||
return null;
|
||||
}
|
||||
if (OverridingUtil.isOverridableBy(context.getSemanticServices().getTypeChecker(), property, declaredProperty).isSuccess()) {
|
||||
if (OverridingUtil.isOverridableBy(property, declaredProperty).isSuccess()) {
|
||||
return property;
|
||||
}
|
||||
return null;
|
||||
@@ -97,6 +97,13 @@ public class OverrideResolver {
|
||||
}
|
||||
|
||||
protected void checkOverridesInAClass(MutableClassDescriptor classDescriptor, JetClassOrObject klass) {
|
||||
// Check overrides for internal consistency
|
||||
for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
|
||||
checkOverride(member);
|
||||
}
|
||||
|
||||
// Check if everything that must be overridden, actually is
|
||||
|
||||
// Everything from supertypes
|
||||
Set<CallableMemberDescriptor> inheritedFunctions = Sets.newLinkedHashSet();
|
||||
for (JetType supertype : classDescriptor.getSupertypes()) {
|
||||
@@ -113,21 +120,21 @@ public class OverrideResolver {
|
||||
|
||||
// Group members with "the same" signature
|
||||
Multimap<CallableMemberDescriptor, CallableMemberDescriptor> factoredMembers = CommonSuppliers.newLinkedHashSetHashSetMultimap();
|
||||
JetTypeChecker typeChecker = context.getSemanticServices().getTypeChecker();
|
||||
for (CallableMemberDescriptor one : filteredMembers) {
|
||||
if (factoredMembers.values().contains(one)) continue;
|
||||
for (CallableMemberDescriptor another : filteredMembers) {
|
||||
if (one == another) continue;
|
||||
factoredMembers.put(one, one);
|
||||
if (OverridingUtil.isOverridableBy(typeChecker, one, another).isSuccess()
|
||||
|| OverridingUtil.isOverridableBy(typeChecker, another, one).isSuccess()) {
|
||||
if (OverridingUtil.isOverridableBy(one, another).isSuccess()
|
||||
|| OverridingUtil.isOverridableBy(another, one).isSuccess()) {
|
||||
factoredMembers.put(one, another);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// More than one implementation or no implementations at all
|
||||
Set<CallableMemberDescriptor> mustBeOverridden = Sets.newLinkedHashSet();
|
||||
Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
|
||||
Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
|
||||
for (CallableMemberDescriptor key : factoredMembers.keySet()) {
|
||||
Collection<CallableMemberDescriptor> mutuallyOverridable = factoredMembers.get(key);
|
||||
|
||||
@@ -138,34 +145,47 @@ public class OverrideResolver {
|
||||
}
|
||||
}
|
||||
|
||||
if (implementationCount != 1) {
|
||||
mustBeOverridden.addAll(mutuallyOverridable);
|
||||
if (implementationCount == 0) {
|
||||
abstractNoImpl.addAll(mutuallyOverridable);
|
||||
}
|
||||
else if (implementationCount > 1) {
|
||||
manyImpl.addAll(mutuallyOverridable);
|
||||
}
|
||||
}
|
||||
|
||||
// Members actually present (declared) in the class
|
||||
Set<CallableDescriptor> actuallyOverridden = Sets.newHashSet();
|
||||
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
||||
actuallyOverridden.addAll(declaredFunction.getOverriddenDescriptors());
|
||||
}
|
||||
for (PropertyDescriptor declaredProperty : classDescriptor.getProperties()) {
|
||||
actuallyOverridden.addAll(declaredProperty.getOverriddenDescriptors());
|
||||
for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
|
||||
actuallyOverridden.addAll(member.getOverriddenDescriptors());
|
||||
}
|
||||
|
||||
// Those to be overridden that are actually not
|
||||
mustBeOverridden.removeAll(actuallyOverridden);
|
||||
abstractNoImpl.removeAll(actuallyOverridden);
|
||||
manyImpl.removeAll(actuallyOverridden);
|
||||
|
||||
// System.out.println(classDescriptor);
|
||||
// println(mustBeOverridden);
|
||||
// System.out.println("Actually overridden:");
|
||||
// println(actuallyOverridden);
|
||||
|
||||
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
||||
checkOverrideForFunction(declaredFunction);
|
||||
PsiElement nameIdentifier = klass;
|
||||
if (klass instanceof JetClass) {
|
||||
nameIdentifier = ((JetClass) klass).getNameIdentifier();
|
||||
}
|
||||
else if (klass instanceof JetObjectDeclaration) {
|
||||
nameIdentifier = ((JetObjectDeclaration) klass).getNameIdentifier();
|
||||
}
|
||||
|
||||
// for (CallableMemberDescriptor memberDescriptor : manyImpl) {
|
||||
// context.getTrace().report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
|
||||
// break;
|
||||
// }
|
||||
|
||||
|
||||
if (classDescriptor.getModality() == Modality.ABSTRACT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// for (CallableMemberDescriptor memberDescriptor : abstractNoImpl) {
|
||||
// context.getTrace().report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
|
||||
// break;
|
||||
// }
|
||||
|
||||
Set<FunctionDescriptor> allOverriddenFunctions = Sets.newHashSet();
|
||||
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
|
||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
||||
@@ -179,13 +199,6 @@ public class OverrideResolver {
|
||||
}
|
||||
}
|
||||
boolean foundError = false;
|
||||
PsiElement nameIdentifier = null;
|
||||
if (klass instanceof JetClass) {
|
||||
nameIdentifier = ((JetClass) klass).getNameIdentifier();
|
||||
}
|
||||
else if (klass instanceof JetObjectDeclaration) {
|
||||
nameIdentifier = ((JetObjectDeclaration) klass).getNameIdentifier();
|
||||
}
|
||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
@@ -194,7 +207,7 @@ public class OverrideResolver {
|
||||
if (declarationDescriptor != classDescriptor) {
|
||||
// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Class '" + klass.getName() + "' must be declared abstract or implement abstract method '" +
|
||||
// functionDescriptor.getName() + "' declared in " + declarationDescriptor.getName());
|
||||
context.getTrace().report(ABSTRACT_METHOD_NOT_IMPLEMENTED.on(nameIdentifier, klass, functionDescriptor, declarationDescriptor));
|
||||
context.getTrace().report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, functionDescriptor));
|
||||
foundError = true;
|
||||
}
|
||||
}
|
||||
@@ -202,32 +215,27 @@ public class OverrideResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void println(Collection<? extends CallableDescriptor> inheritedProperties) {
|
||||
for (CallableDescriptor inheritedProperty : inheritedProperties) {
|
||||
System.out.println(" " + inheritedProperty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkOverrideForFunction(CallableMemberDescriptor declared) {
|
||||
private void checkOverride(CallableMemberDescriptor declared) {
|
||||
JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declared);
|
||||
assert member != null;
|
||||
JetModifierList modifierList = member.getModifierList();
|
||||
ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
|
||||
boolean hasOverrideModifier = overrideNode != null;
|
||||
boolean error = false;
|
||||
|
||||
boolean finalOverriddenError = false;
|
||||
boolean typeMismatchError = false;
|
||||
for (CallableMemberDescriptor overridden : declared.getOverriddenDescriptors()) {
|
||||
if (overridden != null) {
|
||||
if (hasOverrideModifier) {
|
||||
if (!overridden.getModality().isOpen() && !error) {
|
||||
if (!overridden.getModality().isOpen() && !finalOverriddenError) {
|
||||
// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and cannot be overridden");
|
||||
context.getTrace().report(OVERRIDING_FINAL_MEMBER.on(overrideNode, overridden, overridden.getContainingDeclaration()));
|
||||
error = true;
|
||||
finalOverriddenError = true;
|
||||
}
|
||||
|
||||
if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, overridden, declared).isSuccess()) {
|
||||
|
||||
if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, overridden, declared) && !typeMismatchError) {
|
||||
context.getTrace().report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
|
||||
typeMismatchError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ public class OverridingUtil {
|
||||
}
|
||||
for (D other : candidates) {
|
||||
if (me.getOriginal() == other.getOriginal()
|
||||
&& isOverridableBy(JetTypeChecker.INSTANCE, other, me).isSuccess()
|
||||
&& isOverridableBy(JetTypeChecker.INSTANCE, me, other).isSuccess()) {
|
||||
&& isOverridableBy(other, me).isSuccess()
|
||||
&& isOverridableBy(me, other).isSuccess()) {
|
||||
continue outerLoop;
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class OverridingUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverrideCompatibilityInfo isOverridableBy(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||
public static OverrideCompatibilityInfo isOverridableBy(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||
if (!superDescriptor.getName().equals(subDescriptor.getName())) {
|
||||
return OverrideCompatibilityInfo.nameMismatch();
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class OverridingUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverrideCompatibilityInfo isReturnTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||
public static boolean isReturnTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||
List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
|
||||
List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = Maps.newHashMap();
|
||||
@@ -152,10 +152,10 @@ public class OverridingUtil {
|
||||
JetType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getReturnType(), Variance.OUT_VARIANCE);
|
||||
assert substitutedSuperReturnType != null;
|
||||
if (!typeChecker.isSubtypeOf(subDescriptor.getReturnType(), substitutedSuperReturnType)) {
|
||||
return OverrideCompatibilityInfo.returnTypeMismatch(substitutedSuperReturnType, subDescriptor.getReturnType());
|
||||
return false;
|
||||
}
|
||||
|
||||
return OverrideCompatibilityInfo.success();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class OverrideCompatibilityInfo {
|
||||
@@ -194,7 +194,7 @@ public class OverridingUtil {
|
||||
|
||||
@NotNull
|
||||
public static OverrideCompatibilityInfo returnTypeMismatch(JetType substitutedSuperReturnType, JetType unsubstitutedSubReturnType) {
|
||||
return new OverrideCompatibilityInfo(false, "returnTypeMismatch: " + unsubstitutedSubReturnType + " >< " + substitutedSuperReturnType); // TODO
|
||||
return new OverrideCompatibilityInfo(true, "returnTypeMismatch: " + unsubstitutedSubReturnType + " >< " + substitutedSuperReturnType); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompositeTypeSubstitution implements TypeSubstitutor.TypeSubstitution {
|
||||
private final TypeSubstitutor.TypeSubstitution[] inner;
|
||||
|
||||
public CompositeTypeSubstitution(@NotNull TypeSubstitutor.TypeSubstitution... inner) {
|
||||
this.inner = inner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
for (TypeSubstitutor.TypeSubstitution substitution : inner) {
|
||||
TypeProjection value = substitution.get(key);
|
||||
if (value != null) return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (TypeSubstitutor.TypeSubstitution substitution : inner) {
|
||||
if (!substitution.isEmpty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,10 @@ public class TypeSubstitutor {
|
||||
return new TypeSubstitutor(substitution);
|
||||
}
|
||||
|
||||
public static TypeSubstitutor create(@NotNull TypeSubstitution... substitutions) {
|
||||
return create(new CompositeTypeSubstitution(substitutions));
|
||||
}
|
||||
|
||||
public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
return create(new MapToTypeSubstitutionAdapter(substitutionContext));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.resolve;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Renderer;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
@@ -15,7 +16,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class DescriptorRenderer {
|
||||
public class DescriptorRenderer implements Renderer {
|
||||
|
||||
public static String getFQName(DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
@@ -83,6 +84,13 @@ public class DescriptorRenderer {
|
||||
return escape("<");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String render(@Nullable Object object) {
|
||||
assert object instanceof DeclarationDescriptor;
|
||||
return render((DeclarationDescriptor) object);
|
||||
}
|
||||
|
||||
public String render(DeclarationDescriptor declarationDescriptor) {
|
||||
if (declarationDescriptor == null) return lt() + "null>";
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
@@ -33,7 +33,7 @@ class Foo() : <error>WithPC0</error>, <error>this</error>() {
|
||||
|
||||
}
|
||||
|
||||
class WithCPI_Dup(<error>x</error> : Int) {
|
||||
class WithCPI_Dup(x : Int) {
|
||||
var <error>x</error> : Int
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
<info>open</info> class Super(i : Int)
|
||||
|
||||
class TestPCParameters(w : Int, <info>x</info> : Int, val <info>y</info> : Int, var <info>z</info> : Int) : Super(w) {
|
||||
class TestPCParameters(w : Int, x : Int, val <info>y</info> : Int, var <info>z</info> : Int) : Super(w) {
|
||||
|
||||
val <info>xx</info> = w
|
||||
|
||||
@@ -52,6 +52,6 @@ class TestPCParameters(w : Int, <info>x</info> : Int, val <info>y</info> : Int,
|
||||
w + 1
|
||||
}
|
||||
|
||||
fun foo() = x
|
||||
fun foo() = <error>x</error>
|
||||
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
open class NoC
|
||||
class NoC1 : NoC
|
||||
|
||||
@@ -33,8 +32,8 @@ class Foo() : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>WithPC0<!>, <!MANY_C
|
||||
|
||||
}
|
||||
|
||||
class WithCPI_Dup(<!REDECLARATION, REDECLARATION!>x<!> : Int) {
|
||||
var <!REDECLARATION, REDECLARATION, MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>x<!> : Int
|
||||
class WithCPI_Dup(x : Int) {
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>x<!> : Int
|
||||
}
|
||||
|
||||
class WithCPI(x : Int) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
trait A {
|
||||
fun foo() : Int = 1
|
||||
fun foo1() : Int = 1
|
||||
val a : Int
|
||||
val a1 : Int
|
||||
val <T> g : Iterator<T>
|
||||
|
||||
fun <T> g() : T
|
||||
fun <T> g1() : T
|
||||
}
|
||||
|
||||
abstract class B() : A {
|
||||
override fun <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>foo<!>() {
|
||||
}
|
||||
override fun foo() : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Unit<!> {
|
||||
}
|
||||
|
||||
override val a : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Double<!> = 1.dbl
|
||||
override val <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>a1<!> = 1.dbl
|
||||
|
||||
abstract override fun <X> g() : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Int<!>
|
||||
abstract override fun <X> g1() : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>java.util.List<X><!>
|
||||
|
||||
abstract override val <X> g : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Iterator<Int><!>
|
||||
}
|
||||
|
||||
@@ -52,6 +52,6 @@ class TestPCParameters(w : Int, x : Int, val y : Int, var z : Int) : Super(w) {
|
||||
w + 1
|
||||
}
|
||||
|
||||
fun foo() = x
|
||||
fun foo() = <!UNRESOLVED_REFERENCE!>x<!>
|
||||
|
||||
}
|
||||
@@ -16,17 +16,17 @@ namespace normal {
|
||||
|
||||
class MyChildClass : MyClass {}
|
||||
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass<!> : MyTrait, MyAbstractClass {}
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass<!> : MyTrait, MyAbstractClass {}
|
||||
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass2<!> : MyTrait, MyAbstractClass {
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass2<!> : MyTrait, MyAbstractClass {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass3<!> : MyTrait, MyAbstractClass {
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass3<!> : MyTrait, MyAbstractClass {
|
||||
override fun bar() {}
|
||||
}
|
||||
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass4<!> : MyTrait, MyAbstractClass {
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass4<!> : MyTrait, MyAbstractClass {
|
||||
fun <!VIRTUAL_MEMBER_HIDDEN!>foo<!>() {}
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun other() {}
|
||||
}
|
||||
@@ -63,13 +63,13 @@ namespace generics {
|
||||
override fun bar(s: String) = s
|
||||
}
|
||||
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalGenericClass1<!><T> : MyTrait<T>, MyAbstractClass<T> {}
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalGenericClass2<!><T, R> : MyTrait<T>, MyAbstractClass<R> {
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalGenericClass1<!><T> : MyTrait<T>, MyAbstractClass<T> {}
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalGenericClass2<!><T, R> : MyTrait<T>, MyAbstractClass<R> {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(r: R) = r
|
||||
}
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass1<!> : MyTrait<Int>, MyAbstractClass<String> {}
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass1<!> : MyTrait<Int>, MyAbstractClass<String> {}
|
||||
|
||||
class <!ABSTRACT_METHOD_NOT_IMPLEMENTED!>MyIllegalClass2<!><T> : MyTrait<Int>, MyAbstractClass<Int> {
|
||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass2<!><T> : MyTrait<Int>, MyAbstractClass<Int> {
|
||||
fun foo(t: T) = t
|
||||
fun bar(t: T) = t
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ trait Y {
|
||||
abstract val y : Int
|
||||
}
|
||||
|
||||
class YImpl(val y : Int) : Y {}
|
||||
class YImpl(override val y : Int) : Y {}
|
||||
|
||||
class Point(x : Int, yy : Int) : X(x) , Y {
|
||||
override val y : Int = yy
|
||||
|
||||
@@ -139,7 +139,7 @@ public class JetOverridingTest extends LightDaemonAnalyzerTestCase {
|
||||
private void assertOverridabilityRelation(String superFun, String subFun, boolean expectedIsError) {
|
||||
FunctionDescriptor a = makeFunction(superFun);
|
||||
FunctionDescriptor b = makeFunction(subFun);
|
||||
OverridingUtil.OverrideCompatibilityInfo overridableWith = OverridingUtil.isOverridableBy(semanticServices.getTypeChecker(), a, b);
|
||||
OverridingUtil.OverrideCompatibilityInfo overridableWith = OverridingUtil.isOverridableBy(a, b);
|
||||
assertEquals(overridableWith.getMessage(), expectedIsError, !overridableWith.isSuccess());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user