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:
Anna.Kozlova
2016-11-21 10:55:41 +01:00
parent c4be95506d
commit 7ffa9bd6ca
17 changed files with 273 additions and 154 deletions

View File

@@ -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 &amp;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>

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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());
}
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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")

View File

@@ -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) {

View File

@@ -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;
}
}