mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
override/implement annotation settings (IDEA-58379)
annotations are removed by default for both return and parameters, custom OverrideImplementHandlers can provide predefined annotations which must be repeat in overriders, custom annotations can be configured by the user
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
<properties/>
|
||||
<border type="empty"/>
|
||||
<children>
|
||||
<grid id="452da" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="452da" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="10" bottom="0" right="10"/>
|
||||
<constraints/>
|
||||
<properties/>
|
||||
@@ -179,21 +179,9 @@
|
||||
</grid>
|
||||
<vspacer id="91133">
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="5a70" binding="myCommenterPanel" custom-create="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="83565" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
@@ -227,16 +215,15 @@
|
||||
</grid>
|
||||
<component id="be81b" class="javax.swing.JCheckBox" binding="myCbUseExternalAnnotations">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="use.external.annotations"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="6fb9a" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<grid id="6fb9a" binding="myOverridePanel" layout-manager="GridBagLayout">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -247,6 +234,7 @@
|
||||
<component id="95854" class="javax.swing.JCheckBox" binding="myInsertOverrideAnnotationCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="1.0" weighty="0.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="insert.override.annotation"/>
|
||||
@@ -255,6 +243,7 @@
|
||||
<component id="9c14a" class="javax.swing.JCheckBox" binding="myRepeatSynchronizedCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="1.0" weighty="0.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Repeat &synchronized modifier"/>
|
||||
@@ -262,19 +251,41 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="edade" binding="myVisibilityPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<grid id="e7ca1" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="3" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="1" row-span="2" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="69bbc">
|
||||
<constraints border-constraint="Center"/>
|
||||
</vspacer>
|
||||
<grid id="edade" binding="myVisibilityPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="69bbc">
|
||||
<constraints border-constraint="West"/>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="5a70" binding="myCommenterPanel" custom-create="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -17,19 +17,24 @@ package com.intellij.application.options;
|
||||
|
||||
import com.intellij.application.options.codeStyle.CommenterForm;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.JavaVisibilityPanel;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.SortedListModel;
|
||||
import com.intellij.ui.ToolbarDecorator;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -62,7 +67,9 @@ public class CodeStyleGenerationConfigurable implements Configurable {
|
||||
private JPanel myVisibilityPanel;
|
||||
|
||||
@SuppressWarnings("unused") private JPanel myCommenterPanel;
|
||||
private JPanel myOverridePanel;
|
||||
private CommenterForm myCommenterForm;
|
||||
private SortedListModel<String> myRepeatAnnotationsModel;
|
||||
|
||||
public CodeStyleGenerationConfigurable(CodeStyleSettings settings) {
|
||||
mySettings = settings;
|
||||
@@ -76,6 +83,13 @@ public class CodeStyleGenerationConfigurable implements Configurable {
|
||||
.disableAddAction().disableRemoveAction().createPanel();
|
||||
myMembersPanel.add(panel, BorderLayout.CENTER);
|
||||
myVisibilityPanel.add(myJavaVisibilityPanel, BorderLayout.CENTER);
|
||||
GridBagConstraints gc =
|
||||
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, GridBagConstraints.NORTHEAST, GridBagConstraints.BOTH,
|
||||
new JBInsets(0, 0, 0, 0), 0, 0);
|
||||
final Condition<PsiClass> isApplicable = aClass -> aClass.isAnnotationType();
|
||||
//noinspection Convert2Diamond
|
||||
myRepeatAnnotationsModel = new SortedListModel<String>(Comparator.naturalOrder());
|
||||
myOverridePanel.add(SpecialAnnotationsUtil.createSpecialAnnotationsListControl("Annotations to Repeat", false, isApplicable, myRepeatAnnotationsModel), gc);
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@@ -111,7 +125,9 @@ public class CodeStyleGenerationConfigurable implements Configurable {
|
||||
myInsertOverrideAnnotationCheckBox.setSelected(settings.INSERT_OVERRIDE_ANNOTATION);
|
||||
myRepeatSynchronizedCheckBox.setSelected(settings.REPEAT_SYNCHRONIZED);
|
||||
myJavaVisibilityPanel.setVisibility(settings.VISIBILITY);
|
||||
|
||||
|
||||
myRepeatAnnotationsModel.clear();
|
||||
myRepeatAnnotationsModel.addAll(settings.getRepeatAnnotations());
|
||||
myCommenterForm.reset(settings);
|
||||
}
|
||||
|
||||
@@ -144,6 +160,7 @@ public class CodeStyleGenerationConfigurable implements Configurable {
|
||||
myMembersOrderList.apply(settings);
|
||||
|
||||
myCommenterForm.apply(settings);
|
||||
settings.setRepeatAnnotations(myRepeatAnnotationsModel.getItems());
|
||||
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
DaemonCodeAnalyzer.getInstance(project).settingsChanged();
|
||||
@@ -188,6 +205,8 @@ public class CodeStyleGenerationConfigurable implements Configurable {
|
||||
|
||||
isModified |= myCommenterForm.isModified(settings);
|
||||
|
||||
isModified |= !myRepeatAnnotationsModel.getItems().equals(settings.getRepeatAnnotations());
|
||||
|
||||
return isModified;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -30,7 +30,6 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -251,7 +250,7 @@ public class GenerateConstructorHandler extends GenerateMembersHandlerBase {
|
||||
String name = param.getName();
|
||||
assert name != null : param;
|
||||
PsiParameter newParam = factory.createParameter(name, param.getType(), aClass);
|
||||
GenerateMembersUtil.copyOrReplaceModifierList(param, newParam);
|
||||
GenerateMembersUtil.copyOrReplaceModifierList(param, aClass, newParam);
|
||||
constructor.getParameterList().add(newParam);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
|
||||
@@ -26,13 +24,8 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
@@ -405,7 +398,7 @@ public class GenerateMembersUtil {
|
||||
final PsiParameter[] newParameters = overriddenParameters(parameters, factory, codeStyleManager, substitutor, target);
|
||||
for (int i = 0; i < newParameters.length; i++) {
|
||||
final PsiParameter newParameter = newParameters[i];
|
||||
copyOrReplaceModifierList(parameters[i], newParameter);
|
||||
copyOrReplaceModifierList(parameters[i], target, newParameter);
|
||||
targetParameterList.add(newParameter);
|
||||
}
|
||||
}
|
||||
@@ -566,51 +559,24 @@ public class GenerateMembersUtil {
|
||||
OverrideImplementUtil.annotateOnOverrideImplement(method, base, overridden);
|
||||
}
|
||||
|
||||
/**
|
||||
* to be deleted in 2017.2
|
||||
*/
|
||||
@Deprecated
|
||||
public static void copyOrReplaceModifierList(@NotNull PsiModifierListOwner sourceParam, @NotNull PsiModifierListOwner targetParam) {
|
||||
copyOrReplaceModifierList(sourceParam, null, targetParam);
|
||||
}
|
||||
|
||||
public static void copyOrReplaceModifierList(@NotNull PsiModifierListOwner sourceParam, @Nullable PsiElement targetClass, @NotNull PsiModifierListOwner targetParam) {
|
||||
PsiModifierList sourceModifierList = sourceParam.getModifierList();
|
||||
PsiModifierList targetModifierList = targetParam.getModifierList();
|
||||
|
||||
if (sourceModifierList != null && targetModifierList != null) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(targetModifierList);
|
||||
final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null;
|
||||
final Project project = targetModifierList.getProject();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
JVMElementFactory factory = JVMElementFactories.requireFactory(targetParam.getLanguage(), targetParam.getProject());
|
||||
for (PsiAnnotation annotation : AnnotationUtil.getAllAnnotations(sourceParam, false, null, false)) {
|
||||
final String qualifiedName = annotation.getQualifiedName();
|
||||
if (qualifiedName != null && (moduleScope == null || facade.findClass(qualifiedName, moduleScope) != null) &&
|
||||
!AnnotationTargetUtil.isTypeAnnotation(annotation)) {
|
||||
targetModifierList.add(factory.createAnnotationFromText(annotation.getText(), sourceParam));
|
||||
}
|
||||
}
|
||||
for (@PsiModifier.ModifierConstant String m : PsiModifier.MODIFIERS) {
|
||||
targetModifierList.setModifierProperty(m, sourceParam.hasModifierProperty(m));
|
||||
}
|
||||
|
||||
filterAnnotations(sourceModifierList.getProject(), targetModifierList, targetModifierList.getResolveScope());
|
||||
}
|
||||
}
|
||||
|
||||
private static void filterAnnotations(Project project, PsiModifierList modifierList, GlobalSearchScope moduleScope) {
|
||||
Set<String> toRemove = new HashSet<>();
|
||||
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
for (PsiAnnotation annotation : modifierList.getAnnotations()) {
|
||||
String qualifiedName = annotation.getQualifiedName();
|
||||
if (qualifiedName != null) {
|
||||
for (OverrideImplementsAnnotationsHandler handler : Extensions.getExtensions(OverrideImplementsAnnotationsHandler.EP_NAME)) {
|
||||
String[] annotations2Remove = handler.annotationsToRemove(project, qualifiedName);
|
||||
Collections.addAll(toRemove, annotations2Remove);
|
||||
if (moduleScope != null && psiFacade.findClass(qualifiedName, moduleScope) == null) {
|
||||
toRemove.add(qualifiedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String fqn : toRemove) {
|
||||
PsiAnnotation psiAnnotation = modifierList.findAnnotation(fqn);
|
||||
if (psiAnnotation != null) {
|
||||
psiAnnotation.delete();
|
||||
}
|
||||
OverrideImplementsAnnotationsHandler.repeatAnnotationsFromSource(sourceParam, targetClass, targetParam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -45,8 +45,6 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
@@ -58,7 +56,6 @@ import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -246,24 +243,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
|
||||
AddAnnotationPsiFix.addPhysicalAnnotation(overrideAnnotationName, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
|
||||
}
|
||||
}
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(targetClass);
|
||||
final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null;
|
||||
final Project project = targetClass.getProject();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
for (OverrideImplementsAnnotationsHandler each : Extensions.getExtensions(OverrideImplementsAnnotationsHandler.EP_NAME)) {
|
||||
for (String annotation : each.getAnnotations(project)) {
|
||||
if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
|
||||
if (AnnotationUtil.isAnnotated(overridden, annotation, false, false) && !AnnotationUtil.isAnnotated(method, annotation, false, false)) {
|
||||
PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(overridden, annotation);
|
||||
if (psiAnnotation != null && AnnotationUtil.isInferredAnnotation(psiAnnotation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddAnnotationPsiFix.removePhysicalAnnotations(method, each.annotationsToRemove(project, annotation));
|
||||
AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, method.getModifierList());
|
||||
}
|
||||
}
|
||||
}
|
||||
OverrideImplementsAnnotationsHandler.repeatAnnotationsFromSource(overridden, targetClass, method);
|
||||
}
|
||||
|
||||
public static void annotate(@NotNull PsiMethod result, String fqn, String... annosToRemove) throws IncorrectOperationException {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -20,14 +20,54 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface OverrideImplementsAnnotationsHandler {
|
||||
ExtensionPointName<OverrideImplementsAnnotationsHandler> EP_NAME = ExtensionPointName.create("com.intellij.overrideImplementsAnnotationsHandler");
|
||||
|
||||
/**
|
||||
* By default no annotations from source method return type and parameters are repeated.
|
||||
*
|
||||
* Return annotations which should be copied from the source to the implementation.
|
||||
*/
|
||||
String[] getAnnotations(Project project);
|
||||
|
||||
@Deprecated
|
||||
@NotNull
|
||||
String [] annotationsToRemove(Project project, @NotNull String fqName);
|
||||
default String [] annotationsToRemove(Project project, @NotNull String fqName) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
static void repeatAnnotationsFromSource(PsiModifierListOwner source, @Nullable PsiElement targetClass, PsiModifierListOwner target) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(targetClass != null ? targetClass : target);
|
||||
final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null;
|
||||
final Project project = target.getProject();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
for (OverrideImplementsAnnotationsHandler each : Extensions.getExtensions(EP_NAME)) {
|
||||
for (String annotation : each.getAnnotations(project)) {
|
||||
if (moduleScope != null && facade.findClass(annotation, moduleScope) == null) continue;
|
||||
if (AnnotationUtil.isAnnotated(source, annotation, false, false) &&
|
||||
!AnnotationUtil.isAnnotated(target, annotation, false, false)) {
|
||||
|
||||
PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotation(source, annotation);
|
||||
if (psiAnnotation != null && AnnotationUtil.isInferredAnnotation(psiAnnotation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddAnnotationPsiFix.addPhysicalAnnotation(annotation, PsiNameValuePair.EMPTY_ARRAY, target.getModifierList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -23,9 +23,9 @@ package com.intellij.codeInsight.generation;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -37,22 +37,8 @@ public class OverrideImplementsAnnotationsHandlerImpl implements OverrideImpleme
|
||||
final Collection<String> anns = new ArrayList<>(manager.getNotNulls());
|
||||
anns.addAll(manager.getNullables());
|
||||
anns.add(AnnotationUtil.NLS);
|
||||
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project);
|
||||
anns.addAll(settings.getRepeatAnnotations());
|
||||
return ArrayUtil.toStringArray(anns);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String[] annotationsToRemove(Project project, @NotNull final String fqName) {
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
|
||||
if (manager.getNotNulls().contains(fqName)) {
|
||||
return ArrayUtil.toStringArray(manager.getNullables());
|
||||
}
|
||||
if (manager.getNullables().contains(fqName)) {
|
||||
return ArrayUtil.toStringArray(manager.getNotNulls());
|
||||
}
|
||||
if (Comparing.strEqual(fqName, AnnotationUtil.NLS)){
|
||||
return new String[]{AnnotationUtil.NON_NLS};
|
||||
}
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -42,6 +42,7 @@ import javax.swing.*;
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import javax.swing.event.ListDataListener;
|
||||
import java.awt.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -62,13 +63,12 @@ public class SpecialAnnotationsUtil {
|
||||
final String borderTitle,
|
||||
final boolean acceptPatterns,
|
||||
final Condition<PsiClass> isApplicable) {
|
||||
final SortedListModel<String> listModel = new SortedListModel<>((o1, o2) -> o1.compareTo(o2));
|
||||
final JList injectionList = new JBList(listModel);
|
||||
@SuppressWarnings("Convert2Diamond")
|
||||
SortedListModel<String> listModel = new SortedListModel<String>(Comparator.naturalOrder());
|
||||
for (String s : list) {
|
||||
listModel.add(s);
|
||||
}
|
||||
injectionList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
|
||||
injectionList.getModel().addListDataListener(new ListDataListener() {
|
||||
listModel.addListDataListener(new ListDataListener() {
|
||||
@Override
|
||||
public void intervalAdded(ListDataEvent e) {
|
||||
listChanged();
|
||||
@@ -91,7 +91,16 @@ public class SpecialAnnotationsUtil {
|
||||
listChanged();
|
||||
}
|
||||
});
|
||||
return createSpecialAnnotationsListControl(borderTitle, acceptPatterns, isApplicable, listModel);
|
||||
}
|
||||
|
||||
public static JPanel createSpecialAnnotationsListControl(final String borderTitle,
|
||||
final boolean acceptPatterns,
|
||||
final Condition<PsiClass> isApplicable,
|
||||
final SortedListModel<String> listModel) {
|
||||
final JList injectionList = new JBList(listModel);
|
||||
|
||||
injectionList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
|
||||
ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(injectionList)
|
||||
.setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
|
||||
@@ -13,16 +13,16 @@ class Test {
|
||||
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(myOs, test.myOs)) return false;
|
||||
// Compare nested arrays - values of myIIs here
|
||||
if (!Arrays.deepEquals(myIIs, test.myIIs)) return false;
|
||||
if (!Arrays.equals(myIs, test.myIs)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = myOs != null ? myOs.hashCode() : 0;
|
||||
result = 31 * result + (myIIs != null ? myIIs.hashCode() : 0);
|
||||
result = 31 * result + (myIs != null ? myIs.hashCode() : 0);
|
||||
int result = Arrays.hashCode(myOs);
|
||||
result = 31 * result + Arrays.deepHashCode(myIIs);
|
||||
result = 31 * result + Arrays.hashCode(myIs);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class Arrays {
|
||||
int[] i;
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -13,8 +13,8 @@ class Arrays {
|
||||
return true;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return i != null ? i.hashCode() : 0;
|
||||
return java.util.Arrays.hashCode(i);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class Test {
|
||||
int i;
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -13,7 +13,7 @@ class Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Integer {
|
||||
int i;
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -13,7 +13,7 @@ class Integer {
|
||||
return true;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ class Test {
|
||||
class Integer {
|
||||
int i;
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@@ -15,7 +15,7 @@ class Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
|
||||
/**
|
||||
* @author dsl
|
||||
*/
|
||||
@@ -67,8 +79,4 @@ public class GenerateEqualsTest extends GenerateEqualsTestCase {
|
||||
doTest(new int[]{0}, new int[]{0}, new int[0], true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk14();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,13 @@ package com.intellij.codeInsight
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil
|
||||
import com.intellij.codeInsight.generation.OverrideImplementsAnnotationsHandler
|
||||
import com.intellij.idea.ActionsBundle
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.extensions.ExtensionPoint
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
@@ -217,6 +221,84 @@ class Test implements A {
|
||||
}""".stripIndent()
|
||||
}
|
||||
|
||||
void testCustomOverrideImplementsHandler() {
|
||||
myFixture.addClass """package a; public @interface A { }"""
|
||||
|
||||
myFixture.configureByText "test.java", """\
|
||||
import java.util.*;
|
||||
import a.*;
|
||||
|
||||
interface I {
|
||||
@A List<String> i(@A String p);
|
||||
}
|
||||
|
||||
class C implements I {
|
||||
<caret>
|
||||
}""".stripIndent()
|
||||
|
||||
invokeAction(true)
|
||||
|
||||
myFixture.checkResult """\
|
||||
import java.util.*;
|
||||
import a.*;
|
||||
|
||||
interface I {
|
||||
@A List<String> i(@A String p);
|
||||
}
|
||||
|
||||
class C implements I {
|
||||
@Override
|
||||
public List<String> i(String p) {
|
||||
return null;
|
||||
}
|
||||
}""".stripIndent()
|
||||
|
||||
ExtensionPoint<OverrideImplementsAnnotationsHandler> point = Extensions.getRootArea().getExtensionPoint(OverrideImplementsAnnotationsHandler.EP_NAME);
|
||||
OverrideImplementsAnnotationsHandler extension = new OverrideImplementsAnnotationsHandler() {
|
||||
@Override
|
||||
String[] getAnnotations(Project project) {
|
||||
return ["a.A"]
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
point.registerExtension(extension)
|
||||
myFixture.configureByText "test.java", """\
|
||||
import java.util.*;
|
||||
import a.*;
|
||||
|
||||
interface I {
|
||||
@A List<String> i(@A String p);
|
||||
}
|
||||
|
||||
class C implements I {
|
||||
<caret>
|
||||
}""".stripIndent()
|
||||
|
||||
invokeAction(true)
|
||||
|
||||
myFixture.checkResult """\
|
||||
import java.util.*;
|
||||
import a.*;
|
||||
|
||||
interface I {
|
||||
@A List<String> i(@A String p);
|
||||
}
|
||||
|
||||
class C implements I {
|
||||
@A
|
||||
@Override
|
||||
public List<String> i(@A String p) {
|
||||
return null;
|
||||
}
|
||||
}""".stripIndent()
|
||||
|
||||
}
|
||||
finally {
|
||||
point.unregisterExtension(extension)
|
||||
}
|
||||
}
|
||||
|
||||
private void doTest(boolean toImplement) {
|
||||
String name = getTestName(false)
|
||||
myFixture.configureByFile("before${name}.java")
|
||||
|
||||
@@ -57,6 +57,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
|
||||
private final UserDataHolder myUserDataHolder = new UserDataHolderBase();
|
||||
|
||||
@NonNls private static final String REPEAT_ANNOTATIONS = "REPEAT_ANNOTATIONS";
|
||||
@NonNls private static final String ADDITIONAL_INDENT_OPTIONS = "ADDITIONAL_INDENT_OPTIONS";
|
||||
|
||||
@NonNls private static final String FILETYPE = "fileType";
|
||||
@@ -255,7 +256,18 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
//----------------- override -------------------
|
||||
public boolean REPEAT_SYNCHRONIZED = true;
|
||||
|
||||
//----------------- IMPORTS --------------------
|
||||
private List<String> myRepeatAnnotations = new ArrayList<>();
|
||||
|
||||
public List<String> getRepeatAnnotations() {
|
||||
return myRepeatAnnotations;
|
||||
}
|
||||
|
||||
public void setRepeatAnnotations(List<String> repeatAnnotations) {
|
||||
myRepeatAnnotations.clear();
|
||||
myRepeatAnnotations.addAll(repeatAnnotations);
|
||||
}
|
||||
|
||||
//----------------- IMPORTS --------------------
|
||||
|
||||
public boolean LAYOUT_STATIC_IMPORTS_SEPARATELY = true;
|
||||
public boolean USE_FQ_CLASS_NAMES;
|
||||
@@ -507,6 +519,14 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
}
|
||||
}
|
||||
|
||||
myRepeatAnnotations.clear();
|
||||
Element annotations = element.getChild(REPEAT_ANNOTATIONS);
|
||||
if (annotations != null) {
|
||||
for (Element anno : annotations.getChildren("ANNO")) {
|
||||
myRepeatAnnotations.add(anno.getAttributeValue("name"));
|
||||
}
|
||||
}
|
||||
|
||||
UnknownElementCollector unknownElementCollector = new UnknownElementCollector();
|
||||
for (CustomCodeStyleSettings settings : getCustomSettingsValues()) {
|
||||
settings.getKnownTagNames().forEach(unknownElementCollector::addKnownName);
|
||||
@@ -568,6 +588,13 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
}
|
||||
|
||||
myCommonSettingsManager.writeExternal(element);
|
||||
if (!myRepeatAnnotations.isEmpty()) {
|
||||
Element annos = new Element(REPEAT_ANNOTATIONS);
|
||||
for (String annotation : myRepeatAnnotations) {
|
||||
annos.addContent(new Element("ANNO").setAttribute("name", annotation));
|
||||
}
|
||||
element.addContent(annos);
|
||||
}
|
||||
}
|
||||
|
||||
private static IndentOptions getDefaultIndentOptions(FileType fileType) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -22,18 +22,10 @@ package com.theoryinpractice.testng.intention;
|
||||
|
||||
import com.intellij.codeInsight.generation.OverrideImplementsAnnotationsHandler;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.theoryinpractice.testng.util.TestNGUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class OverrideImplementsTestNGAnnotationsHandler implements OverrideImplementsAnnotationsHandler{
|
||||
public String[] getAnnotations(Project project) {
|
||||
return TestNGUtil.CONFIG_ANNOTATIONS_FQN;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String[] annotationsToRemove(Project project, @NotNull final String fqName) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user