mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
AnnotateCapitalizationIntention
This commit is contained in:
+3
-2
@@ -23,17 +23,18 @@ import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.PsiNameValuePair;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class AddAnnotationFix extends AddAnnotationPsiFix implements IntentionAction {
|
||||
public AddAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner modifierListOwner, @NotNull String... annotationsToRemove) {
|
||||
public AddAnnotationFix(@NotNull String fqn, @Nullable PsiModifierListOwner modifierListOwner, @NotNull String... annotationsToRemove) {
|
||||
this(fqn, modifierListOwner, PsiNameValuePair.EMPTY_ARRAY, annotationsToRemove);
|
||||
}
|
||||
|
||||
public AddAnnotationFix(@NotNull String fqn,
|
||||
@NotNull PsiModifierListOwner modifierListOwner,
|
||||
@Nullable PsiModifierListOwner modifierListOwner,
|
||||
@NotNull PsiNameValuePair[] values,
|
||||
@NotNull String... annotationsToRemove) {
|
||||
super(fqn, modifierListOwner, values, annotationsToRemove);
|
||||
|
||||
+9
-6
@@ -37,10 +37,10 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
protected final String myAnnotation;
|
||||
protected final String[] myAnnotationsToRemove;
|
||||
protected final PsiNameValuePair[] myPairs; // not used when registering local quick fix
|
||||
protected final String myText;
|
||||
protected String myText;
|
||||
|
||||
public AddAnnotationPsiFix(@NotNull String fqn,
|
||||
@NotNull PsiModifierListOwner modifierListOwner,
|
||||
@Nullable PsiModifierListOwner modifierListOwner,
|
||||
@NotNull PsiNameValuePair[] values,
|
||||
@NotNull String... annotationsToRemove) {
|
||||
super(modifierListOwner);
|
||||
@@ -117,26 +117,29 @@ public class AddAnnotationPsiFix extends LocalQuickFixOnPsiElement {
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner)startElement;
|
||||
|
||||
final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project);
|
||||
invoke(project, file, (PsiModifierListOwner)startElement, myPairs);
|
||||
}
|
||||
|
||||
protected void invoke(@NotNull Project project, @NotNull PsiFile file, PsiModifierListOwner myModifierListOwner, PsiNameValuePair[] pairs) {
|
||||
final PsiModifierList modifierList = myModifierListOwner.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
if (modifierList.findAnnotation(myAnnotation) != null) return;
|
||||
final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project);
|
||||
final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace = annotationsManager.chooseAnnotationsPlace(myModifierListOwner);
|
||||
if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return;
|
||||
if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) {
|
||||
for (String fqn : myAnnotationsToRemove) {
|
||||
annotationsManager.deannotate(myModifierListOwner, fqn);
|
||||
}
|
||||
annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs);
|
||||
annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, pairs);
|
||||
}
|
||||
else {
|
||||
final PsiFile containingFile = myModifierListOwner.getContainingFile();
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(containingFile)) return;
|
||||
removePhysicalAnnotations(myModifierListOwner, myAnnotationsToRemove);
|
||||
|
||||
PsiAnnotation inserted = addPhysicalAnnotation(myAnnotation, myPairs, modifierList);
|
||||
PsiAnnotation inserted = addPhysicalAnnotation(myAnnotation, pairs, modifierList);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted);
|
||||
if (containingFile != file) {
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
|
||||
@@ -257,10 +257,6 @@ class Foo {
|
||||
assert 'Bar' in myFixture.lookupElementStrings
|
||||
}
|
||||
|
||||
private Editor getEditor() {
|
||||
return myFixture.getEditor();
|
||||
}
|
||||
|
||||
private void checkResult() {
|
||||
checkResultByFile(getTestName(false) + "-out.java");
|
||||
}
|
||||
|
||||
+3
@@ -16,6 +16,7 @@
|
||||
package com.intellij.testFramework.fixtures;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -154,6 +155,8 @@ public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{
|
||||
|
||||
protected PsiFile getFile() { return myFixture.getFile(); }
|
||||
|
||||
protected Editor getEditor() { return myFixture.getEditor(); }
|
||||
|
||||
protected PsiManager getPsiManager() {
|
||||
return PsiManager.getInstance(getProject());
|
||||
}
|
||||
|
||||
+2
-1
@@ -22,13 +22,14 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class LocalQuickFixOnPsiElement implements LocalQuickFix {
|
||||
protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.LocalQuickFixAndIntentionAction");
|
||||
protected final SmartPsiElementPointer<PsiElement> myStartElement;
|
||||
protected final SmartPsiElementPointer<PsiElement> myEndElement;
|
||||
|
||||
protected LocalQuickFixOnPsiElement(@NotNull PsiElement element) {
|
||||
protected LocalQuickFixOnPsiElement(@Nullable PsiElement element) {
|
||||
this(element, element);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public class BaseListPopupStep<T> extends BaseStep<T> implements ListPopupStep<T
|
||||
private List<Icon> myIcons;
|
||||
private int myDefaultOptionIndex = -1;
|
||||
|
||||
public BaseListPopupStep(@Nullable String title, T[] values) {
|
||||
public BaseListPopupStep(@Nullable String title, T... values) {
|
||||
this(title, values, new Icon[]{});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.ui.popup.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -579,4 +581,13 @@ public class ListPopupImpl extends WizardPopup implements ListPopup {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showInBestPositionFor(@NotNull Editor editor) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
handleSelect(true);
|
||||
}
|
||||
else {
|
||||
super.showInBestPositionFor(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -75,7 +75,10 @@ public class CodeInsightTestUtil {
|
||||
|
||||
@TestOnly
|
||||
public static void doIntentionTest(CodeInsightTestFixture fixture, @NonNls String file, @NonNls String actionText) {
|
||||
doIntentionTest(fixture, actionText, file + ".xml", file + "_after.xml");
|
||||
String extension = FileUtilRt.getExtension(file);
|
||||
file = FileUtil.getNameWithoutExtension(file);
|
||||
if (extension.isEmpty()) extension = "xml";
|
||||
doIntentionTest(fixture, actionText, file + "." + extension, file + "_after." + extension);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
@@ -136,6 +136,11 @@
|
||||
groupKey="inspections.group.name" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="org.jetbrains.idea.devkit.inspections.internal.UnsafeReturnStatementVisitorInspection" />
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.idea.devkit.inspections.AnnotateCapitalizationIntention</className>
|
||||
<category>I18N</category>
|
||||
</intentionAction>
|
||||
|
||||
<moduleConfigurationEditorProvider implementation="org.jetbrains.idea.devkit.module.PluginModuleEditorsProvider"/>
|
||||
<implicitUsageProvider implementation="org.jetbrains.idea.devkit.inspections.DevKitImplicitUsageProvider"/>
|
||||
<psi.referenceContributor implementation="org.jetbrains.idea.devkit.dom.impl.I18nReferenceContributor"/>
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
void setTitle(@Nls(capitalization = Nls.Capitalization.Title) String title) {
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
void setTitle(String title) {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Annotate with capitalization type.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class AnnotateCapitalizationIntention extends AddAnnotationFix {
|
||||
|
||||
public AnnotateCapitalizationIntention() {
|
||||
super(Nls.class.getName(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
PsiModifierListOwner element = getElement(editor, file);
|
||||
if (element == null ||
|
||||
(!ApplicationManager.getApplication().isUnitTestMode() && element.getManager().isInProject(element)) ||
|
||||
AnnotationUtil.findAnnotation(element, Nls.class.getName()) != null) return false;
|
||||
myText = "Annotate capitalization type";
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Annotate capitalization type";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||
final PsiModifierListOwner modifierListOwner = getElement(editor, file);
|
||||
if (modifierListOwner == null) throw new IncorrectOperationException();
|
||||
|
||||
BaseListPopupStep<Nls.Capitalization> step =
|
||||
new BaseListPopupStep<Nls.Capitalization>(null, Nls.Capitalization.Title, Nls.Capitalization.Sentence) {
|
||||
@Override
|
||||
public PopupStep onChosen(final Nls.Capitalization selectedValue, boolean finalChoice) {
|
||||
new WriteCommandAction.Simple(project) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
String nls = Nls.class.getName();
|
||||
PsiAnnotation annotation = JavaPsiFacade.getInstance(project).getElementFactory()
|
||||
.createAnnotationFromText("@" + nls + "(capitalization = " +
|
||||
nls + ".Capitalization." + selectedValue.toString() + ")", modifierListOwner);
|
||||
invoke(project, file, modifierListOwner, annotation.getParameterList().getAttributes());
|
||||
}
|
||||
}.execute();
|
||||
return FINAL_CHOICE;
|
||||
}
|
||||
};
|
||||
JBPopupFactory.getInstance().createListPopup(step).showInBestPositionFor(editor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiModifierListOwner getElement(Editor editor, PsiFile file) {
|
||||
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
|
||||
if (parameter == null) return null;
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
|
||||
if (method == null) return null;
|
||||
PsiType type = parameter.getType();
|
||||
return type.equalsToText(CommonClassNames.JAVA_LANG_STRING) ? parameter : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
class Intention {
|
||||
void setTitle(String ti<caret>tle) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import org.jetbrains.annotations.Nls;
|
||||
|
||||
class Intention {
|
||||
void setTitle(@Nls(capitalization = Nls.Capitalization.Title) String title) {
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,16 @@ public class CapitalizationInspectionTest extends LightCodeInsightFixtureTestCas
|
||||
assertEmpty(myFixture.filterAvailableIntentions("Properly capitalize"));
|
||||
}
|
||||
|
||||
public void doTest(boolean fix) {
|
||||
public void testIntention() throws Exception {
|
||||
myFixture.configureByFile("Intention.java");
|
||||
AnnotateCapitalizationIntention intention = new AnnotateCapitalizationIntention();
|
||||
assertTrue(intention.isAvailable(getProject(), getEditor(), getFile()));
|
||||
intention.invoke(getProject(), getEditor(), getFile());
|
||||
myFixture.checkResultByFile("Intention_after.java");
|
||||
assertFalse(intention.isAvailable(getProject(), getEditor(), getFile()));
|
||||
}
|
||||
|
||||
private void doTest(boolean fix) {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
if (!fix) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user