Added API in PSI to add/remove modifiers and refactored quickfixes to use it
This commit is contained in:
@@ -27,9 +27,11 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lang.psi.addRemoveModifier.AddRemoveModifierPackage;
|
||||
import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
|
||||
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -90,6 +92,31 @@ public class JetClass extends JetTypeParameterListOwnerStub<PsiJetClassStub> imp
|
||||
return getStubOrPsiChild(JetStubElementTypes.PRIMARY_CONSTRUCTOR_MODIFIER_LIST);
|
||||
}
|
||||
|
||||
public void addPrimaryConstructorModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
JetModifierList modifierList = getPrimaryConstructorModifierList();
|
||||
if (modifierList != null) {
|
||||
AddRemoveModifierPackage.addModifier(modifierList, modifier, JetTokens.PUBLIC_KEYWORD);
|
||||
}
|
||||
else {
|
||||
if (modifier == JetTokens.PUBLIC_KEYWORD) return;
|
||||
|
||||
JetParameterList parameterList = getPrimaryConstructorParameterList();
|
||||
assert parameterList != null;
|
||||
JetModifierList newModifierList = new JetPsiFactory(getProject()).createModifierList(modifier);
|
||||
addBefore(newModifierList, parameterList);
|
||||
}
|
||||
}
|
||||
|
||||
public void removePrimaryConstructorModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
JetModifierList list = getPrimaryConstructorModifierList();
|
||||
if (list != null) {
|
||||
PsiElement token = list.getModifier(modifier);
|
||||
if (token != null) {
|
||||
token.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JetClassInitializer> getAnonymousInitializers() {
|
||||
|
||||
@@ -20,7 +20,9 @@ import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lang.psi.addRemoveModifier.AddRemoveModifierPackage;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -37,11 +39,21 @@ abstract class JetDeclarationImpl extends JetExpressionImpl implements JetDeclar
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModifier(JetModifierKeywordToken modifier) {
|
||||
public boolean hasModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
JetModifierList modifierList = getModifierList();
|
||||
return modifierList != null && modifierList.hasModifier(modifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
AddRemoveModifierPackage.addModifier(this, modifier, JetTokens.INTERNAL_KEYWORD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
AddRemoveModifierPackage.removeModifier(this, modifier);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetAnnotationEntry> getAnnotationEntries() {
|
||||
|
||||
@@ -62,21 +62,7 @@ public abstract class JetModifierList extends JetElementImplStub<PsiJetModifierL
|
||||
return answer != null ? answer : Collections.<JetAnnotationEntry>emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ASTNode> getModifierNodes() {
|
||||
List<ASTNode> modifierNodes = new ArrayList<ASTNode>();
|
||||
|
||||
ASTNode node = getNode().getFirstChildNode();
|
||||
while (node != null) {
|
||||
if (node.getElementType() instanceof JetModifierKeywordToken) {
|
||||
modifierNodes.add(node);
|
||||
}
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
return modifierNodes;
|
||||
}
|
||||
|
||||
public boolean hasModifier(JetModifierKeywordToken token) {
|
||||
public boolean hasModifier(@NotNull JetModifierKeywordToken token) {
|
||||
PsiJetModifierListStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.hasModifier(token);
|
||||
@@ -85,12 +71,12 @@ public abstract class JetModifierList extends JetElementImplStub<PsiJetModifierL
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getModifier(JetModifierKeywordToken token) {
|
||||
public PsiElement getModifier(@NotNull JetModifierKeywordToken token) {
|
||||
return findChildByType(token);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ASTNode getModifierNode(JetToken token) {
|
||||
public ASTNode getModifierNode(@NotNull JetToken token) {
|
||||
ASTNode node = getNode().getFirstChildNode();
|
||||
while (node != null) {
|
||||
if (node.getElementType() == token) return node;
|
||||
@@ -98,6 +84,4 @@ public abstract class JetModifierList extends JetElementImplStub<PsiJetModifierL
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
|
||||
@@ -24,5 +25,8 @@ public interface JetModifierListOwner extends PsiElement, JetAnnotated {
|
||||
@Nullable
|
||||
JetModifierList getModifierList();
|
||||
|
||||
boolean hasModifier(JetModifierKeywordToken modifier);
|
||||
boolean hasModifier(@NotNull JetModifierKeywordToken modifier);
|
||||
|
||||
void addModifier(@NotNull JetModifierKeywordToken modifier);
|
||||
void removeModifier(@NotNull JetModifierKeywordToken modifier);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,10 @@ import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.addRemoveModifier.AddRemoveModifierPackage;
|
||||
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -43,11 +45,21 @@ public class JetModifierListOwnerStub<T extends StubElement> extends JetElementI
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModifier(JetModifierKeywordToken modifier) {
|
||||
public boolean hasModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
JetModifierList modifierList = getModifierList();
|
||||
return modifierList != null && modifierList.hasModifier(modifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
AddRemoveModifierPackage.addModifier(this, modifier, JetTokens.INTERNAL_KEYWORD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
AddRemoveModifierPackage.removeModifier(this, modifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JetAnnotationEntry> getAnnotationEntries() {
|
||||
|
||||
@@ -110,7 +110,7 @@ public class JetObjectDeclaration extends JetNamedDeclarationStub<PsiJetObjectSt
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModifier(JetModifierKeywordToken modifier) {
|
||||
public boolean hasModifier(@NotNull JetModifierKeywordToken modifier) {
|
||||
JetModifierList modifierList = getModifierList();
|
||||
return modifierList != null && modifierList.hasModifier(modifier);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.psi.addRemoveModifier
|
||||
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken
|
||||
import org.jetbrains.jet.lexer.JetTokens.*
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.psi.JetAnnotation
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.siblings
|
||||
|
||||
internal fun addModifier(owner: JetModifierListOwner, modifier: JetModifierKeywordToken, defaultVisibilityModifier: JetModifierKeywordToken) {
|
||||
val modifierList = owner.getModifierList()
|
||||
if (modifierList == null) {
|
||||
if (modifier == defaultVisibilityModifier) return
|
||||
|
||||
val newModifierList = JetPsiFactory(owner).createModifierList(modifier)
|
||||
val anchor = owner.getFirstChild()!!.siblings(forward = true)
|
||||
.dropWhile { it is PsiComment || it is PsiWhiteSpace }
|
||||
.first()
|
||||
owner.addBefore(newModifierList, anchor)
|
||||
}
|
||||
else {
|
||||
addModifier(modifierList, modifier, defaultVisibilityModifier)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun addModifier(modifierList: JetModifierList, modifier: JetModifierKeywordToken, defaultVisibilityModifier: JetModifierKeywordToken) {
|
||||
val newModifier = JetPsiFactory(modifierList).createModifierList(modifier).getModifier(modifier)!!
|
||||
val modifierToReplace = MODIFIERS_TO_REPLACE[modifier]
|
||||
?.map { modifierList.getModifier(it) }
|
||||
?.filterNotNull()
|
||||
?.firstOrNull()
|
||||
|
||||
if (modifier == defaultVisibilityModifier) { // do not insert explicit 'internal' keyword (or 'public' for primary constructor)
|
||||
//TODO: code style option
|
||||
if (modifierToReplace != null) {
|
||||
modifierToReplace.delete()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (modifierToReplace != null) {
|
||||
modifierToReplace.replace(newModifier)
|
||||
}
|
||||
else {
|
||||
val newModifierOrder = MODIFIERS_ORDER.indexOf(modifier)
|
||||
|
||||
fun placeAfter(child: PsiElement): Boolean {
|
||||
if (child is PsiWhiteSpace) return false
|
||||
if (child is JetAnnotation) return true // place modifiers after annotations
|
||||
val elementType = child.getNode()!!.getElementType()
|
||||
val order = MODIFIERS_ORDER.indexOf(elementType)
|
||||
return newModifierOrder > order
|
||||
}
|
||||
|
||||
val anchor = modifierList.getLastChild()?.siblings(forward = false)?.firstOrNull(::placeAfter)
|
||||
modifierList.addAfter(newModifier, anchor)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun removeModifier(owner: JetModifierListOwner, modifier: JetModifierKeywordToken) {
|
||||
owner.getModifierList()?.getModifier(modifier)?.delete()
|
||||
}
|
||||
|
||||
private val MODIFIERS_TO_REPLACE = mapOf(
|
||||
ABSTRACT_KEYWORD to listOf(OPEN_KEYWORD, FINAL_KEYWORD),
|
||||
OVERRIDE_KEYWORD to listOf(OPEN_KEYWORD),
|
||||
OPEN_KEYWORD to listOf(FINAL_KEYWORD),
|
||||
PUBLIC_KEYWORD to listOf(PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD),
|
||||
PROTECTED_KEYWORD to listOf(PUBLIC_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD),
|
||||
PRIVATE_KEYWORD to listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, INTERNAL_KEYWORD),
|
||||
INTERNAL_KEYWORD to listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD)
|
||||
)
|
||||
|
||||
private val MODIFIERS_ORDER = listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD,
|
||||
FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD,
|
||||
OVERRIDE_KEYWORD,
|
||||
INNER_KEYWORD,
|
||||
ANNOTATION_KEYWORD, ENUM_KEYWORD)
|
||||
@@ -131,6 +131,8 @@ fun createSpacingBuilder(settings: CodeStyleSettings): KotlinSpacingBuilder {
|
||||
aroundInside(ARROW, FUNCTION_TYPE).spaceIf(jetSettings.SPACE_AROUND_FUNCTION_TYPE_ARROW)
|
||||
|
||||
betweenInside(REFERENCE_EXPRESSION, FUNCTION_LITERAL_ARGUMENT, CALL_EXPRESSION).spaces(1)
|
||||
|
||||
betweenInside(IDENTIFIER, MODIFIER_LIST, CLASS).spaces(1)
|
||||
}
|
||||
custom {
|
||||
|
||||
|
||||
@@ -23,31 +23,22 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.psi.PsiPackage.JetPsiFactory;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.ABSTRACT_KEYWORD;
|
||||
|
||||
public class AddModifierFix extends JetIntentionAction<JetModifierListOwner> {
|
||||
private final JetKeywordToken modifier;
|
||||
private final JetModifierKeywordToken[] modifiersThanCanBeReplaced;
|
||||
@NotNull private final JetModifierKeywordToken modifier;
|
||||
|
||||
private AddModifierFix(@NotNull JetModifierListOwner element, @NotNull JetKeywordToken modifier, @Nullable JetModifierKeywordToken[] modifiersThanCanBeReplaced) {
|
||||
private AddModifierFix(@NotNull JetModifierListOwner element, @NotNull JetModifierKeywordToken modifier) {
|
||||
super(element);
|
||||
this.modifier = modifier;
|
||||
this.modifiersThanCanBeReplaced = modifiersThanCanBeReplaced;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -85,78 +76,7 @@ public class AddModifierFix extends JetIntentionAction<JetModifierListOwner> {
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException {
|
||||
element.replace(addModifier(element, modifier, modifiersThanCanBeReplaced, project, false));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ static JetModifierListOwner addModifier(@NotNull PsiElement element, @NotNull JetKeywordToken modifier, @Nullable JetModifierKeywordToken[] modifiersThatCanBeReplaced, @NotNull Project project, boolean toBeginning) {
|
||||
JetModifierListOwner newElement = (JetModifierListOwner) (element.copy());
|
||||
changeModifier(newElement, newElement.getModifierList(), newElement.getFirstChild(),
|
||||
modifiersThatCanBeReplaced, project, toBeginning, JetPsiFactory(project).createModifierList(modifier));
|
||||
return newElement;
|
||||
}
|
||||
|
||||
public static void changeModifier(
|
||||
PsiElement element, @Nullable JetModifierList modifierList, @Nullable PsiElement insertAnchor,
|
||||
JetModifierKeywordToken[] modifiersThatCanBeReplaced, Project project, boolean toBeginning, JetModifierList listWithModifier
|
||||
) {
|
||||
PsiElement whiteSpace = JetPsiFactory(project).createWhiteSpace();
|
||||
if (modifierList == null) {
|
||||
if (listWithModifier != null) {
|
||||
if (insertAnchor != null) {
|
||||
listWithModifier = (JetModifierList) element.addBefore(listWithModifier, insertAnchor);
|
||||
element.addBefore(whiteSpace, insertAnchor);
|
||||
element.addBefore(whiteSpace, listWithModifier);
|
||||
}
|
||||
else {
|
||||
PsiElement firstChild = element.getFirstChild();
|
||||
element.addBefore(listWithModifier, firstChild);
|
||||
element.addBefore(whiteSpace, firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean replaced = false;
|
||||
if (modifiersThatCanBeReplaced != null) {
|
||||
PsiElement toBeReplaced = null;
|
||||
PsiElement toReplace = null;
|
||||
for (JetModifierKeywordToken modifierThatCanBeReplaced : modifiersThatCanBeReplaced) {
|
||||
if (modifierList.hasModifier(modifierThatCanBeReplaced)) {
|
||||
PsiElement modifierElement = modifierList.getModifierNode(modifierThatCanBeReplaced).getPsi();
|
||||
assert modifierElement != null;
|
||||
if (!replaced && listWithModifier != null) {
|
||||
toBeReplaced = modifierElement;
|
||||
toReplace = listWithModifier.getFirstChild();
|
||||
//modifierElement.replace(listWithModifier.getFirstChild());
|
||||
replaced = true;
|
||||
}
|
||||
else {
|
||||
modifierList.deleteChildInternal(modifierElement.getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toBeReplaced != null && toReplace != null) {
|
||||
toBeReplaced.replace(toReplace);
|
||||
}
|
||||
}
|
||||
if (!replaced && listWithModifier != null) {
|
||||
if (toBeginning) {
|
||||
PsiElement firstChild = modifierList.getFirstChild();
|
||||
modifierList.addBefore(listWithModifier.getFirstChild(), firstChild);
|
||||
modifierList.addBefore(whiteSpace, firstChild);
|
||||
}
|
||||
else {
|
||||
PsiElement lastChild = modifierList.getLastChild();
|
||||
modifierList.addAfter(listWithModifier.getFirstChild(), lastChild);
|
||||
modifierList.addAfter(whiteSpace, lastChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ static JetModifierListOwner addModifierWithDefaultReplacement(@NotNull PsiElement element, @NotNull JetModifierKeywordToken modifier, @NotNull Project project, boolean toBeginning) {
|
||||
return addModifier(element, modifier, MODIFIERS_THAT_CAN_BE_REPLACED.get(modifier), project, toBeginning);
|
||||
element.addModifier(modifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +90,7 @@ public class AddModifierFix extends JetIntentionAction<JetModifierListOwner> {
|
||||
public IntentionAction createAction(Diagnostic diagnostic) {
|
||||
JetModifierListOwner modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, modifierOwnerClass);
|
||||
if (modifierListOwner == null) return null;
|
||||
return new AddModifierFix(modifierListOwner, modifier, MODIFIERS_THAT_CAN_BE_REPLACED.get(modifier));
|
||||
return new AddModifierFix(modifierListOwner, modifier);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -178,11 +98,4 @@ public class AddModifierFix extends JetIntentionAction<JetModifierListOwner> {
|
||||
public static JetSingleIntentionActionFactory createFactory(JetModifierKeywordToken modifier) {
|
||||
return createFactory(modifier, JetModifierListOwner.class);
|
||||
}
|
||||
|
||||
private static Map<JetModifierKeywordToken, JetModifierKeywordToken[]> MODIFIERS_THAT_CAN_BE_REPLACED = new HashMap<JetModifierKeywordToken, JetModifierKeywordToken[]>();
|
||||
static {
|
||||
MODIFIERS_THAT_CAN_BE_REPLACED.put(ABSTRACT_KEYWORD, new JetModifierKeywordToken[]{OPEN_KEYWORD, FINAL_KEYWORD});
|
||||
MODIFIERS_THAT_CAN_BE_REPLACED.put(OVERRIDE_KEYWORD, new JetModifierKeywordToken[]{OPEN_KEYWORD});
|
||||
MODIFIERS_THAT_CAN_BE_REPLACED.put(OPEN_KEYWORD, new JetModifierKeywordToken[]{FINAL_KEYWORD});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ public class AddOpenModifierToClassDeclarationFix extends JetIntentionAction<Jet
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException {
|
||||
classDeclaration.replace(AddModifierFix.addModifierWithDefaultReplacement(classDeclaration, JetTokens.OPEN_KEYWORD, project, false));
|
||||
classDeclaration.addModifier(JetTokens.OPEN_KEYWORD);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+6
-10
@@ -25,11 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.jet.plugin.project.PluginJetFilesProvider;
|
||||
@@ -37,11 +33,10 @@ import org.jetbrains.jet.plugin.project.PluginJetFilesProvider;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.PUBLIC_KEYWORD;
|
||||
|
||||
public class AddOverrideToEqualsHashCodeToStringFix extends JetIntentionAction<PsiElement> {
|
||||
private static final JetModifierKeywordToken[] MODIFIERS_TO_REPLACE = {PUBLIC_KEYWORD, OPEN_KEYWORD};
|
||||
|
||||
public AddOverrideToEqualsHashCodeToStringFix(@NotNull PsiElement element) {
|
||||
super(element);
|
||||
}
|
||||
@@ -90,10 +85,11 @@ public class AddOverrideToEqualsHashCodeToStringFix extends JetIntentionAction<P
|
||||
for (Diagnostic diagnostic : ResolvePackage.getBindingContext(jetFile).getDiagnostics()) {
|
||||
if (diagnostic.getFactory() != Errors.VIRTUAL_MEMBER_HIDDEN) continue;
|
||||
|
||||
PsiElement element = diagnostic.getPsiElement();
|
||||
JetModifierListOwner element = (JetModifierListOwner) diagnostic.getPsiElement();
|
||||
if (!isEqualsHashCodeOrToString(element)) continue;
|
||||
|
||||
element.replace(AddModifierFix.addModifier(element, OVERRIDE_KEYWORD, MODIFIERS_TO_REPLACE, project, false));
|
||||
element.addModifier(OVERRIDE_KEYWORD);
|
||||
element.removeModifier(PUBLIC_KEYWORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
||||
@@ -31,7 +32,6 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
@@ -66,11 +66,13 @@ public class ChangeVisibilityModifierFix extends JetIntentionAction<JetModifierL
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException {
|
||||
JetKeywordToken modifier = findVisibilityChangeTo(file);
|
||||
element.replace(AddModifierFix.addModifier(element, modifier, VISIBILITY_TOKENS, project, true));
|
||||
JetModifierKeywordToken modifier = findVisibilityChangeTo(file);
|
||||
assert modifier != null;
|
||||
element.addModifier(modifier);
|
||||
}
|
||||
|
||||
private JetKeywordToken findVisibilityChangeTo(JetFile file) {
|
||||
@Nullable
|
||||
private JetModifierKeywordToken findVisibilityChangeTo(JetFile file) {
|
||||
BindingContext bindingContext = ResolvePackage.getBindingContext(file);
|
||||
DeclarationDescriptor descriptor;
|
||||
if (element instanceof JetParameter) {
|
||||
|
||||
@@ -83,7 +83,7 @@ public class MakeClassAnAnnotationClassFix extends JetIntentionAction<JetAnnotat
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException {
|
||||
annotationClass.replace(AddModifierFix.addModifier(annotationClass, ANNOTATION_KEYWORD, null, project, false));
|
||||
annotationClass.addModifier(ANNOTATION_KEYWORD);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.psi.JetCallableDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
@@ -43,7 +44,7 @@ import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorT
|
||||
import static org.jetbrains.jet.lexer.JetTokens.OPEN_KEYWORD;
|
||||
|
||||
public class MakeOverriddenMemberOpenFix extends JetIntentionAction<JetDeclaration> {
|
||||
private final List<PsiElement> overriddenNonOverridableMembers = new ArrayList<PsiElement>();
|
||||
private final List<JetCallableDeclaration> overriddenNonOverridableMembers = new ArrayList<JetCallableDeclaration>();
|
||||
private final List<String> containingDeclarationsNames = new ArrayList<String>();
|
||||
|
||||
public MakeOverriddenMemberOpenFix(@NotNull JetDeclaration declaration) {
|
||||
@@ -68,11 +69,11 @@ public class MakeOverriddenMemberOpenFix extends JetIntentionAction<JetDeclarati
|
||||
(CallableMemberDescriptor) descriptor)) {
|
||||
assert overriddenDescriptor.getKind() == DECLARATION : "Can only be applied to declarations.";
|
||||
PsiElement overriddenMember = descriptorToDeclaration(overriddenDescriptor);
|
||||
if (overriddenMember == null || !QuickFixUtil.canModifyElement(overriddenMember)) {
|
||||
if (overriddenMember == null || !QuickFixUtil.canModifyElement(overriddenMember) || !(overriddenMember instanceof JetCallableDeclaration)) {
|
||||
return false;
|
||||
}
|
||||
String containingDeclarationName = overriddenDescriptor.getContainingDeclaration().getName().asString();
|
||||
overriddenNonOverridableMembers.add(overriddenMember);
|
||||
overriddenNonOverridableMembers.add((JetCallableDeclaration) overriddenMember);
|
||||
containingDeclarationsNames.add(containingDeclarationName);
|
||||
}
|
||||
return overriddenNonOverridableMembers.size() > 0;
|
||||
@@ -142,8 +143,8 @@ public class MakeOverriddenMemberOpenFix extends JetIntentionAction<JetDeclarati
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException {
|
||||
for (PsiElement overriddenMember : overriddenNonOverridableMembers) {
|
||||
overriddenMember.replace(AddModifierFix.addModifierWithDefaultReplacement(overriddenMember, OPEN_KEYWORD, project, false));
|
||||
for (JetCallableDeclaration overriddenMember : overriddenNonOverridableMembers) {
|
||||
overriddenMember.addModifier(OPEN_KEYWORD);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils;
|
||||
@@ -69,7 +69,8 @@ public class JetRefactoringUtil {
|
||||
private JetRefactoringUtil() {
|
||||
}
|
||||
|
||||
public static JetKeywordToken getVisibilityToken(Visibility visibility) {
|
||||
@NotNull
|
||||
public static JetModifierKeywordToken getVisibilityToken(@NotNull Visibility visibility) {
|
||||
if (visibility == Visibilities.PUBLIC) {
|
||||
return JetTokens.PUBLIC_KEYWORD;
|
||||
}
|
||||
|
||||
+18
-23
@@ -21,10 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.quickfix.AddModifierFix;
|
||||
import org.jetbrains.jet.plugin.quickfix.ChangeVisibilityModifierFix;
|
||||
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeInfo;
|
||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
||||
@@ -66,22 +63,26 @@ public class JetFunctionDefinitionUsage extends JetUsageInfo<PsiElement> {
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
parameterList = ((JetClass) element).getPrimaryConstructorParameterList();
|
||||
}
|
||||
|
||||
if (changeInfo.isParameterSetOrOrderChanged()) {
|
||||
String parametersText = changeInfo.getNewParametersSignature(element, isInherited, 0);
|
||||
JetParameterList newParameterList = psiFactory.createParameterList(parametersText);
|
||||
|
||||
if (parameterList != null)
|
||||
parameterList = (JetParameterList) parameterList.replace(newParameterList);
|
||||
if (parameterList != null) {
|
||||
parameterList.replace(newParameterList);
|
||||
}
|
||||
else if (element instanceof JetClass) {
|
||||
PsiElement anchor = ((JetClass) element).getTypeParameterList();
|
||||
|
||||
if (anchor == null)
|
||||
if (anchor == null) {
|
||||
anchor = ((JetClass) element).getNameIdentifier();
|
||||
if (anchor != null)
|
||||
parameterList = (JetParameterList) element.addAfter(newParameterList, anchor);
|
||||
}
|
||||
if (anchor != null) {
|
||||
element.addAfter(newParameterList, anchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parameterList != null) {
|
||||
@@ -93,27 +94,21 @@ public class JetFunctionDefinitionUsage extends JetUsageInfo<PsiElement> {
|
||||
}
|
||||
}
|
||||
|
||||
if (changeInfo.isVisibilityChanged())
|
||||
changeVisibility(changeInfo, element, parameterList);
|
||||
if (changeInfo.isVisibilityChanged() && !JetPsiUtil.isLocal((JetDeclaration) element)) {
|
||||
changeVisibility(changeInfo, element);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void changeVisibility(JetChangeInfo changeInfo, PsiElement element, JetParameterList parameterList) {
|
||||
JetKeywordToken newVisibilityToken = JetRefactoringUtil.getVisibilityToken(changeInfo.getNewVisibility());
|
||||
private static void changeVisibility(JetChangeInfo changeInfo, PsiElement element) {
|
||||
JetModifierKeywordToken newVisibilityToken = JetRefactoringUtil.getVisibilityToken(changeInfo.getNewVisibility());
|
||||
|
||||
JetPsiFactory psiFactory = JetPsiFactory(getProject());
|
||||
if (element instanceof JetFunction) {
|
||||
JetModifierList modifierList = newVisibilityToken == JetTokens.INTERNAL_KEYWORD ? null :
|
||||
psiFactory.createModifierList(newVisibilityToken);
|
||||
AddModifierFix.changeModifier(element, ((JetFunction) element).getModifierList(), null,
|
||||
ChangeVisibilityModifierFix.VISIBILITY_TOKENS, getProject(), true, modifierList);
|
||||
((JetFunction)element).addModifier(newVisibilityToken);
|
||||
}
|
||||
else {
|
||||
JetModifierList modifierList = newVisibilityToken == JetTokens.PUBLIC_KEYWORD ? null :
|
||||
psiFactory.createConstructorModifierList(newVisibilityToken);
|
||||
AddModifierFix.changeModifier(element, ((JetClass) element).getPrimaryConstructorModifierList(), parameterList,
|
||||
ChangeVisibilityModifierFix.VISIBILITY_TOKENS, getProject(), true, modifierList);
|
||||
((JetClass)element).addPrimaryConstructorModifier(newVisibilityToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' abstract" "true"
|
||||
public abstract class A() {
|
||||
<caret>abstract var i : Int
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' abstract" "true"
|
||||
public class A() {
|
||||
<caret>abstract var i : Int
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' open" "true"
|
||||
public open class A() {
|
||||
<caret>open fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' open" "true"
|
||||
deprecated("") open class A() {
|
||||
<caret>open fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' open" "true"
|
||||
public class A() {
|
||||
<caret>open fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' open" "true"
|
||||
deprecated("") class A() {
|
||||
<caret>open fun foo() {}
|
||||
}
|
||||
@@ -79,6 +79,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeAbstractPropertyInNonAbstractClass3.kt")
|
||||
public void testAbstractPropertyInNonAbstractClass3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/beforeAbstractPropertyInNonAbstractClass3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeAbstractPropertyInPrimaryConstructorParameters.kt")
|
||||
public void testAbstractPropertyInPrimaryConstructorParameters() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/abstract/beforeAbstractPropertyInPrimaryConstructorParameters.kt");
|
||||
@@ -1768,6 +1774,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeOpenMemberInFinalClass3.kt")
|
||||
public void testOpenMemberInFinalClass3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/beforeOpenMemberInFinalClass3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeOpenMemberInFinalClass4.kt")
|
||||
public void testOpenMemberInFinalClass4() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/beforeOpenMemberInFinalClass4.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("beforeOpenModifierInEnum.kt")
|
||||
public void testOpenModifierInEnum() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/beforeOpenModifierInEnum.kt");
|
||||
|
||||
Reference in New Issue
Block a user