'add primary constructor fix' changed to 'change to invocation fix' (for delegators to super class)

This commit is contained in:
svtk
2012-01-24 16:32:52 +04:00
parent 70d0cd882b
commit 428681f1d3
8 changed files with 90 additions and 75 deletions
@@ -140,7 +140,7 @@ public interface Errors {
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 SUPERTYPE_NOT_INITIALIZED_DEFAULT = SimpleDiagnosticFactory.create(ERROR, "Constructor invocation should be explicitly specified");
SimplePsiElementOnlyDiagnosticFactory<JetDelegatorToSuperClass> SUPERTYPE_NOT_INITIALIZED_DEFAULT = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "Constructor invocation should be explicitly specified");
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");
@@ -148,26 +148,23 @@ public class BodyResolver {
JetTypeReference typeReference = specifier.getTypeReference();
JetType supertype = context.getTrace().getBindingContext().get(BindingContext.TYPE, typeReference);
recordSupertype(typeReference, supertype);
if (supertype != null) {
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
if (descriptor.getKind() != ClassKind.TRAIT) {
if (classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) {
boolean hasConstructorWithoutParams = false;
for (ConstructorDescriptor constructor : classDescriptor.getConstructors()) {
if (constructor.getValueParameters().isEmpty()) {
hasConstructorWithoutParams = true;
}
}
if (!hasConstructorWithoutParams) {
context.getTrace().report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
}
else {
context.getTrace().report(SUPERTYPE_NOT_INITIALIZED_DEFAULT.on(specifier));
}
}
if (supertype == null) return;
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor == null) return;
if (descriptor.getKind() != ClassKind.TRAIT && classDescriptor.hasConstructors() &&
!ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) {
boolean hasConstructorWithoutParams = false;
for (ConstructorDescriptor constructor : classDescriptor.getConstructors()) {
if (constructor.getValueParameters().isEmpty()) {
hasConstructorWithoutParams = true;
}
}
if (!hasConstructorWithoutParams) {
context.getTrace().report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
}
else {
context.getTrace().report(SUPERTYPE_NOT_INITIALIZED_DEFAULT.on(specifier));
}
}
}
@@ -1,7 +1,6 @@
#quick fix messages
add.function.body=Add function body
add.primary.constructor=Add primary constructor to {0}
add.primary.constructor.family=Add primary constructor
change.to.constructor.invocation=Change to constructor invocation
add.return.type=Add return type declaration
change.accessor.type=Change accessor type
change.getter.type=Change getter type to {0}
@@ -1,53 +0,0 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.plugin.JetBundle;
/**
* @author svtk
*/
public class AddPrimaryConstructorFix extends JetIntentionAction<JetClass> {
public AddPrimaryConstructorFix(@NotNull JetClass element) {
super(element);
}
@NotNull
@Override
public String getText() {
return JetBundle.message("add.primary.constructor", element.getName());
}
@NotNull
@Override
public String getFamilyName() {
return JetBundle.message("add.primary.constructor.family");
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
JetClass newClass = (JetClass) element.copy();
assert !newClass.hasPrimaryConstructor();
PsiElement primaryConstructor = JetPsiFactory.createPrimaryConstructor(project);
newClass.addAfter(primaryConstructor, newClass.getNameIdentifier());
element.replace(newClass);
}
public static JetIntentionActionFactory<JetClass> createFactory() {
return new JetIntentionActionFactory<JetClass>() {
@Override
public JetIntentionAction<JetClass> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetClass;
return new AddPrimaryConstructorFix((JetClass) diagnostic.getPsiElement());
}
};
}
}
@@ -0,0 +1,57 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperClass;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.plugin.JetBundle;
import java.util.List;
/**
* @author svtk
*/
public class ChangeToInvocationFix extends JetIntentionAction<JetDelegatorToSuperClass> {
public ChangeToInvocationFix(@NotNull JetDelegatorToSuperClass element) {
super(element);
}
@NotNull
@Override
public String getText() {
return JetBundle.message("change.to.constructor.invocation");
}
@NotNull
@Override
public String getFamilyName() {
return JetBundle.message("change.to.constructor.invocation");
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
JetDelegatorToSuperClass delegator = (JetDelegatorToSuperClass) element.copy();
JetClass aClass = JetPsiFactory.createClass(project, "class A : " + delegator.getText() + "()");
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
assert delegationSpecifiers.size() == 1;
JetDelegationSpecifier specifier = delegationSpecifiers.iterator().next();
element.replace(specifier);
}
public static JetIntentionActionFactory<JetDelegatorToSuperClass> createFactory() {
return new JetIntentionActionFactory<JetDelegatorToSuperClass>() {
@Override
public JetIntentionAction<JetDelegatorToSuperClass> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetDelegatorToSuperClass;
return new ChangeToInvocationFix((JetDelegatorToSuperClass) diagnostic.getPsiElement());
}
};
}
}
@@ -87,7 +87,6 @@ public class QuickFixes {
add(Errors.USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory());
JetIntentionActionFactory<JetModifierList> removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory(true);
add(Errors.REDUNDANT_MODIFIER, removeRedundantModifierFactory);
add(Errors.REDUNDANT_MODIFIER_IN_TRAIT, removeRedundantModifierFactory);
@@ -112,6 +111,8 @@ public class QuickFixes {
JetIntentionActionFactory<JetSimpleNameExpression> unresolvedReferenceFactory = ImportClassFix.createFactory();
add(Errors.UNRESOLVED_REFERENCE, unresolvedReferenceFactory);
add(Errors.SUPERTYPE_NOT_INITIALIZED_DEFAULT, ChangeToInvocationFix.createFactory());
ImplementMethodsHandler implementMethodsHandler = new ImplementMethodsHandler();
actionMap.put(Errors.ABSTRACT_MEMBER_NOT_IMPLEMENTED, implementMethodsHandler);
actionMap.put(Errors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED, implementMethodsHandler);
@@ -0,0 +1,7 @@
// "Change to constructor invocation" "true"
open class A {
}
class B : A<caret>() {}
@@ -0,0 +1,7 @@
// "Change to constructor invocation" "true"
open class A {
}
class B : A<caret> {}