Added AddAbstractModifierFix, renamed JetChangeUtil -> JetPsiFactory

This commit is contained in:
svtk
2011-09-15 20:17:09 +04:00
parent ae66babdc2
commit 4b720733c0
22 changed files with 287 additions and 100 deletions
@@ -0,0 +1,39 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author svtk
*/
public abstract class DiagnosticFactoryWithPsiElement1<T extends PsiElement, A> extends DiagnosticFactoryWithMessageFormat {
protected DiagnosticFactoryWithPsiElement1(Severity severity, String message) {
super(severity, message);
}
protected String makeMessage(@NotNull A argument) {
return messageFormat.format(new Object[]{makeMessageFor(argument)});
}
protected String makeMessageFor(A argument) {
return argument.toString();
}
@NotNull
public Diagnostic on(@NotNull T element, @NotNull A argument) {
return on(element, element.getNode(), argument);
}
@NotNull
public Diagnostic on(@NotNull T element, @NotNull ASTNode node, @NotNull A argument) {
return new DiagnosticWithPsiElement<T>(this, severity, makeMessage(argument), element, node.getTextRange());
}
@NotNull
public Diagnostic on(@NotNull T element, @NotNull PsiElement psiElement, @NotNull A argument) {
return new DiagnosticWithPsiElement<T>(this, severity, makeMessage(argument), element, psiElement.getTextRange());
}
}
@@ -1,16 +1,14 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class DiagnosticFactoryWithPsiElement2<A, B> extends DiagnosticFactoryWithMessageFormat {
public static <A, B> DiagnosticFactoryWithPsiElement2<A, B> create(Severity severity, String message) {
return new DiagnosticFactoryWithPsiElement2<A, B>(severity, message);
}
public abstract class DiagnosticFactoryWithPsiElement2<T extends PsiElement, A, B> extends DiagnosticFactoryWithMessageFormat {
public DiagnosticFactoryWithPsiElement2(Severity severity, String message) {
super(severity, message);
@@ -29,7 +27,12 @@ public class DiagnosticFactoryWithPsiElement2<A, B> extends DiagnosticFactoryWit
}
@NotNull
public Diagnostic on(@NotNull PsiElement element, @NotNull A a, @NotNull B b) {
return new DiagnosticWithPsiElement<PsiElement>(this, severity, makeMessage(a, b), element);
public Diagnostic on(@NotNull T element, @NotNull A a, @NotNull B b) {
return on(element, element.getNode(), a, b);
}
@NotNull
public Diagnostic on(@NotNull T element, @NotNull ASTNode node, @NotNull A a, @NotNull B b) {
return new DiagnosticWithPsiElement<T>(this, severity, makeMessage(a, b), element, node.getTextRange());
}
}
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
@@ -21,7 +22,7 @@ public interface Errors {
UnresolvedReferenceDiagnosticFactory UNRESOLVED_REFERENCE = UnresolvedReferenceDiagnosticFactory.INSTANCE;
RedeclarationDiagnosticFactory REDECLARATION = RedeclarationDiagnosticFactory.INSTANCE;
DiagnosticFactoryWithPsiElement2<JetType, JetType> TYPE_MISMATCH = DiagnosticFactoryWithPsiElement2.create(ERROR, "Type mismatch: inferred type is {1} but {0} was expected");
PsiElementOnlyDiagnosticFactory2<PsiElement, JetType, JetType> TYPE_MISMATCH = PsiElementOnlyDiagnosticFactory2.create(ERROR, "Type mismatch: inferred type is {1} but {0} was expected");
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
@@ -54,10 +55,10 @@ public interface Errors {
SimpleDiagnosticFactory PROPERTY_INITIALIZER_NO_BACKING_FIELD = SimpleDiagnosticFactory.create(ERROR, "Initializer is not allowed here because this property has no backing field");
SimpleDiagnosticFactory PROPERTY_INITIALIZER_NO_PRIMARY_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "Property initializers are not allowed when no primary constructor is present");
SimplePsiElementOnlyDiagnosticFactory<JetModifierListOwner> REDUNDANT_ABSTRACT = SimplePsiElementOnlyDiagnosticFactory.create(WARNING, "Abstract modifier is redundant in traits");
ParameterizedDiagnosticFactory2<String, ClassDescriptor> ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS = ParameterizedDiagnosticFactory2.create(ERROR, "Abstract property {0} in non-abstract class {1}");
PsiElementOnlyDiagnosticFactory2<JetModifierListOwner, String, ClassDescriptor> ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS = PsiElementOnlyDiagnosticFactory2.create(ERROR, "Abstract property {0} in non-abstract class {1}");
ParameterizedDiagnosticFactory2<String, ClassDescriptor> ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = ParameterizedDiagnosticFactory2.create(ERROR, "Abstract function {0} in non-abstract class {1}");
ParameterizedDiagnosticFactory1<FunctionDescriptor> ABSTRACT_FUNCTION_WITH_BODY = ParameterizedDiagnosticFactory1.create(ERROR, "A function {0} with body cannot be abstract");
ParameterizedDiagnosticFactory1<FunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = ParameterizedDiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract");
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, FunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract");
ParameterizedDiagnosticFactory1<FunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = ParameterizedDiagnosticFactory1.create(ERROR, "Function {0} is not a class or trait member and cannot be abstract");
SimpleDiagnosticFactory NON_MEMBER_ABSTRACT_ACCESSOR = SimpleDiagnosticFactory.create(ERROR, "This property is not a class or trait member and thus cannot have abstract accessors"); // TODO : Better message
ParameterizedDiagnosticFactory1<FunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = ParameterizedDiagnosticFactory1.create(ERROR, "Function {0} must have a body");
@@ -9,35 +9,22 @@ import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class ParameterizedDiagnosticFactory1<T> extends DiagnosticFactoryWithMessageFormat {
public class ParameterizedDiagnosticFactory1<A> extends DiagnosticFactoryWithPsiElement1<PsiElement, A> {
public static <T> ParameterizedDiagnosticFactory1<T> create(Severity severity, String messageStub) {
return new ParameterizedDiagnosticFactory1<T>(severity, messageStub);
}
public ParameterizedDiagnosticFactory1(Severity severity, String messageStub) {
protected ParameterizedDiagnosticFactory1(Severity severity, String messageStub) {
super(severity, messageStub);
}
private String makeMessage(@NotNull T argument) {
return messageFormat.format(new Object[]{makeMessageFor(argument)});
}
protected String makeMessageFor(T argument) {
return argument.toString();
}
@NotNull
public Diagnostic on(@NotNull PsiFile psiFile, @NotNull TextRange range, @NotNull T argument) {
public Diagnostic on(@NotNull PsiFile psiFile, @NotNull TextRange range, @NotNull A argument) {
return new GenericDiagnostic(this, severity, makeMessage(argument), psiFile, range);
}
@NotNull
public Diagnostic on(@NotNull ASTNode node, @NotNull T argument) {
public Diagnostic on(@NotNull ASTNode node, @NotNull A argument) {
return on(DiagnosticUtils.getContainingFile(node), node.getTextRange(), argument);
}
@NotNull
public Diagnostic on(@NotNull PsiElement element, @NotNull T argument) {
return new DiagnosticWithPsiElement<PsiElement>(this, severity, makeMessage(argument), element);
}
}
@@ -2,13 +2,14 @@ package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class ParameterizedDiagnosticFactory2<A, B> extends DiagnosticFactoryWithPsiElement2<A,B> {
public class ParameterizedDiagnosticFactory2<A, B> extends DiagnosticFactoryWithPsiElement2<PsiElement, A,B> {
public static <A, B> ParameterizedDiagnosticFactory2<A, B> create(Severity severity, String messageStub) {
return new ParameterizedDiagnosticFactory2<A, B>(severity, messageStub);
}
@@ -0,0 +1,15 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.psi.PsiElement;
/**
* @author svtk
*/
public class PsiElementOnlyDiagnosticFactory1<T extends PsiElement, A> extends DiagnosticFactoryWithPsiElement1<T, A> implements PsiElementOnlyDiagnosticFactory<T> {
public static <T extends PsiElement, A> PsiElementOnlyDiagnosticFactory1<T, A> create(Severity severity, String messageStub) {
return new PsiElementOnlyDiagnosticFactory1<T, A>(severity, messageStub);
}
protected PsiElementOnlyDiagnosticFactory1(Severity severity, String message) {
super(severity, message);
}
}
@@ -0,0 +1,16 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.psi.PsiElement;
/**
* @author svtk
*/
public class PsiElementOnlyDiagnosticFactory2<T extends PsiElement, A, B> extends DiagnosticFactoryWithPsiElement2<T, A, B> implements PsiElementOnlyDiagnosticFactory {
public static <T extends PsiElement, A, B> PsiElementOnlyDiagnosticFactory2<T, A, B> create(Severity severity, String messageStub) {
return new PsiElementOnlyDiagnosticFactory2<T, A, B>(severity, messageStub);
}
protected PsiElementOnlyDiagnosticFactory2(Severity severity, String message) {
super(severity, message);
}
}
@@ -9,17 +9,13 @@ import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class SimpleDiagnosticFactory extends DiagnosticFactoryWithSeverity {
public class SimpleDiagnosticFactory extends SimpleDiagnosticFactoryWithPsiElement<PsiElement> {
public static SimpleDiagnosticFactory create(Severity severity, String message) {
return new SimpleDiagnosticFactory(severity, message);
}
protected final String message;
public SimpleDiagnosticFactory(Severity severity, String message) {
super(severity);
this.message = message;
protected SimpleDiagnosticFactory(Severity severity, String message) {
super(severity, message);
}
@NotNull
@@ -31,9 +27,4 @@ public class SimpleDiagnosticFactory extends DiagnosticFactoryWithSeverity {
public Diagnostic on(@NotNull ASTNode node) {
return on(DiagnosticUtils.getContainingFile(node), node.getTextRange());
}
@NotNull
public Diagnostic on(@NotNull PsiElement element) {
return new DiagnosticWithPsiElement<PsiElement>(this, severity, message, element);
}
}
@@ -0,0 +1,28 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
* @author svtk
*/
public abstract class SimpleDiagnosticFactoryWithPsiElement<T extends PsiElement> extends DiagnosticFactoryWithSeverity {
protected final String message;
protected SimpleDiagnosticFactoryWithPsiElement(Severity severity, String message) {
super(severity);
this.message = message;
}
@NotNull
public Diagnostic on(@NotNull T element, @NotNull ASTNode node) {
return new DiagnosticWithPsiElement<T>(this, severity, message, element, node.getTextRange());
}
@NotNull
public Diagnostic on(@NotNull T element) {
return on(element, element.getNode());
}
}
@@ -9,26 +9,13 @@ import org.jetbrains.annotations.NotNull;
/**
* @author svtk
*/
public class SimplePsiElementOnlyDiagnosticFactory<T extends PsiElement> extends DiagnosticFactoryWithSeverity implements PsiElementOnlyDiagnosticFactory<T> {
public class SimplePsiElementOnlyDiagnosticFactory<T extends PsiElement> extends SimpleDiagnosticFactoryWithPsiElement<T> implements PsiElementOnlyDiagnosticFactory<T> {
public static <T extends PsiElement> SimplePsiElementOnlyDiagnosticFactory<T> create(Severity severity, String message) {
return new SimplePsiElementOnlyDiagnosticFactory<T>(severity, message);
}
protected final String message;
public SimplePsiElementOnlyDiagnosticFactory(Severity severity, String message) {
super(severity);
this.message = message;
}
@NotNull
public Diagnostic on(@NotNull T element, @NotNull ASTNode node) {
return new DiagnosticWithPsiElement<T>(this, severity, message, element, node.getTextRange());
}
@NotNull
public Diagnostic on(@NotNull T element) {
return on(element, element.getNode());
protected SimplePsiElementOnlyDiagnosticFactory(Severity severity, String message) {
super(severity, message);
}
}
@@ -29,7 +29,7 @@ public abstract class JetNamedDeclaration extends JetDeclaration implements PsiN
@Override
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
return getNameIdentifier().replace(JetChangeUtil.createNameIdentifier(getProject(), name));
return getNameIdentifier().replace(JetPsiFactory.createNameIdentifier(getProject(), name));
}
@Override
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileFactory;
import com.intellij.util.LocalTimeCounter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.plugin.JetFileType;
import java.util.List;
@@ -12,7 +13,7 @@ import java.util.List;
/**
* @author max
*/
public class JetChangeUtil {
public class JetPsiFactory {
public static JetExpression createExpression(Project project, String text) {
JetProperty property = createProperty(project, "val x = " + text);
return property.getInitializer();
@@ -23,6 +24,16 @@ public class JetChangeUtil {
return property.getPropertyTypeRef();
}
public static PsiElement[] createColon(Project project) {
JetProperty property = createProperty(project, "val x : Int");
return new PsiElement[] { property.findElementAt(5), property.findElementAt(6), property.findElementAt(7) };
}
public static PsiElement createWhiteSpace(Project project) {
JetProperty property = createProperty(project, "val x");
return property.findElementAt(3);
}
public static JetClass createClass(Project project, String text) {
return createDeclaration(project, text, JetClass.class);
}
@@ -58,4 +69,10 @@ public class JetChangeUtil {
public static JetNamedFunction createFunction(Project project, String funDecl) {
return createDeclaration(project, funDecl, JetNamedFunction.class);
}
public static JetModifierList createModifier(Project project, JetKeywordToken modifier) {
String text = modifier.getValue() + " val x";
JetProperty property = createProperty(project, text);
return property.getModifierList();
}
}
@@ -616,7 +616,7 @@ public class BodyResolver {
}
if (!(classDescriptor.getModality() == Modality.ABSTRACT) && classDescriptor.getKind() != ClassKind.ENUM_CLASS) {
// context.getTrace().getErrorHandler().genericError(abstractNode, "Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName());
context.getTrace().report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(abstractNode, property.getName(), classDescriptor));
context.getTrace().report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(property, abstractNode, property.getName(), classDescriptor));
return;
}
if (classDescriptor.getKind() == ClassKind.TRAIT) {
@@ -804,7 +804,7 @@ public class BodyResolver {
}
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null && !isPropertyAccessor) {
// context.getTrace().getErrorHandler().genericError(nameIdentifier.getNode(), "Method " + function.getName() + " without body must be abstract");
context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(nameIdentifier, functionDescriptor));
context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(modifierListOwner, nameIdentifier, functionDescriptor));
}
return;
}