mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
IDEA-87401 CreateAssign -> Bind + +HighPriorityAction + tests added
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.generation.ClassMember;
|
||||
import com.intellij.codeInsight.generation.MemberChooserObject;
|
||||
import com.intellij.codeInsight.generation.PsiMethodMember;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.ide.util.MemberChooser;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -48,7 +49,7 @@ import java.util.*;
|
||||
/**
|
||||
* @author Danila Ponomarenko
|
||||
*/
|
||||
public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction {
|
||||
public class BindFieldsFromParametersAction extends BaseIntentionAction implements HighPriorityAction {
|
||||
private static final Logger LOG = Logger.getInstance(CreateFieldFromParameterAction.class);
|
||||
private static final Key<Map<SmartPsiElementPointer<PsiParameter>, Boolean>> PARAMS = Key.create("FIELDS_FROM_PARAMS");
|
||||
|
||||
@@ -75,7 +76,7 @@ public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction
|
||||
LOG.assertTrue(psiParameter != null);
|
||||
}
|
||||
|
||||
setText(CodeInsightBundle.message("intention.create.assign.fields.from.parameters.text", method.isConstructor() ? "Constructor" : "Method"));
|
||||
setText(CodeInsightBundle.message("intention.bind.fields.from.parameters.text", method.isConstructor() ? "Constructor" : "Method"));
|
||||
}
|
||||
return isAvailable(psiParameter);
|
||||
}
|
||||
@@ -150,7 +151,7 @@ public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return CodeInsightBundle.message("intention.create.assign.fields.from.parameters.family");
|
||||
return CodeInsightBundle.message("intention.bind.fields.from.parameters.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -163,62 +164,94 @@ public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
|
||||
final PsiMethod method = myParameter != null ? (PsiMethod)myParameter.getDeclarationScope() : PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PsiMethod.class);
|
||||
LOG.assertTrue(method != null);
|
||||
final Collection<SmartPsiElementPointer<PsiParameter>> unboundedParams;
|
||||
synchronized (LOCK) {
|
||||
unboundedParams = getUnboundedParams(method);
|
||||
if (unboundedParams.isEmpty()) return;
|
||||
if (myParameter == null) {
|
||||
myParameter = unboundedParams.iterator().next().getElement();
|
||||
}
|
||||
}
|
||||
if (unboundedParams.size() > 1 && isInteractive) {
|
||||
ClassMember[] members = new ClassMember[unboundedParams.size()];
|
||||
ClassMember selection = null;
|
||||
int i = 0;
|
||||
for (SmartPsiElementPointer<PsiParameter> pointer : unboundedParams) {
|
||||
final PsiParameter parameter = pointer.getElement();
|
||||
final ParameterClassMember classMember = new ParameterClassMember(parameter);
|
||||
members[i++] = classMember;
|
||||
if (parameter == myParameter) {
|
||||
selection = classMember;
|
||||
}
|
||||
}
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
Arrays.sort(members, new Comparator<ClassMember>() {
|
||||
@Override
|
||||
public int compare(ClassMember o1, ClassMember o2) {
|
||||
return parameterList.getParameterIndex(((ParameterClassMember)o1).getParameter()) -
|
||||
parameterList.getParameterIndex(((ParameterClassMember)o2).getParameter());
|
||||
}
|
||||
});
|
||||
|
||||
final MemberChooser<ClassMember> chooser = new MemberChooser<ClassMember>(members, false, true, project);
|
||||
if (selection != null) {
|
||||
chooser.selectElements(new ClassMember[]{selection});
|
||||
}
|
||||
chooser.setTitle("Choose " + (method.isConstructor() ? "Constructor" : "Method") + " Parameters");
|
||||
chooser.setCopyJavadocVisible(false);
|
||||
chooser.show();
|
||||
if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
|
||||
final List<ClassMember> selectedElements = chooser.getSelectedElements();
|
||||
if (selectedElements == null) return;
|
||||
|
||||
final HashSet<String> usedNames = new HashSet<String>();
|
||||
for (ClassMember selectedElement : selectedElements) {
|
||||
processParameter(project, ((ParameterClassMember)selectedElement).getParameter(), usedNames);
|
||||
}
|
||||
}
|
||||
else {
|
||||
processParameter(project, myParameter);
|
||||
}
|
||||
synchronized (LOCK) {
|
||||
unboundedParams.clear();
|
||||
final HashSet<String> usedNames = new HashSet<String>();
|
||||
for (PsiParameter selected : selectParameters(project, method, copyUnboundedParamsAndClearOriginal(method), isInteractive)) {
|
||||
processParameter(project, selected, usedNames);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processParameter(final Project project,
|
||||
final PsiParameter myParameter) {
|
||||
processParameter(project, myParameter, new HashSet<String>());
|
||||
@NotNull
|
||||
private static Iterable<PsiParameter> selectParameters(@NotNull Project project,
|
||||
@NotNull PsiMethod method,
|
||||
@NotNull Collection<SmartPsiElementPointer<PsiParameter>> unboundedParams,
|
||||
boolean isInteractive) {
|
||||
if (unboundedParams.size() < 2 || !isInteractive) {
|
||||
return revealPointers(unboundedParams);
|
||||
}
|
||||
|
||||
final ParameterClassMember[] members = sortByParameterIndex(toClassMemberArray(unboundedParams), method);
|
||||
|
||||
final MemberChooser<ParameterClassMember> chooser = showChooser(project, method, members);
|
||||
|
||||
final List<ParameterClassMember> selectedElements = chooser.getSelectedElements();
|
||||
if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE || selectedElements == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return revealParameterClassMembers(selectedElements);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MemberChooser<ParameterClassMember> showChooser(@NotNull Project project,
|
||||
@NotNull PsiMethod method,
|
||||
@NotNull ParameterClassMember[] members) {
|
||||
final MemberChooser<ParameterClassMember> chooser = new MemberChooser<ParameterClassMember>(members, false, true, project);
|
||||
chooser.selectElements(members);
|
||||
chooser.setTitle("Choose " + (method.isConstructor() ? "Constructor" : "Method") + " Parameters");
|
||||
chooser.show();
|
||||
return chooser;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ParameterClassMember[] sortByParameterIndex(@NotNull ParameterClassMember[] members, @NotNull PsiMethod method) {
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
Arrays.sort(members, new Comparator<ParameterClassMember>() {
|
||||
@Override
|
||||
public int compare(ParameterClassMember o1, ParameterClassMember o2) {
|
||||
return parameterList.getParameterIndex(o1.getParameter()) -
|
||||
parameterList.getParameterIndex(o2.getParameter());
|
||||
}
|
||||
});
|
||||
return members;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <T extends PsiElement> List<T> revealPointers(@NotNull Iterable<SmartPsiElementPointer<T>> pointers) {
|
||||
final List<T> result = new ArrayList<T>();
|
||||
for (SmartPsiElementPointer<T> pointer : pointers) {
|
||||
result.add(pointer.getElement());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiParameter> revealParameterClassMembers(@NotNull Iterable<ParameterClassMember> parameterClassMembers) {
|
||||
final List<PsiParameter> result = new ArrayList<PsiParameter>();
|
||||
for (ParameterClassMember parameterClassMember : parameterClassMembers) {
|
||||
result.add(parameterClassMember.getParameter());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ParameterClassMember[] toClassMemberArray(@NotNull Collection<SmartPsiElementPointer<PsiParameter>> unboundedParams) {
|
||||
final ParameterClassMember[] result = new ParameterClassMember[unboundedParams.size()];
|
||||
int i = 0;
|
||||
for (SmartPsiElementPointer<PsiParameter> pointer : unboundedParams) {
|
||||
result[i++] = new ParameterClassMember(pointer.getElement());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<SmartPsiElementPointer<PsiParameter>> copyUnboundedParamsAndClearOriginal(@NotNull PsiMethod method) {
|
||||
synchronized (LOCK) {
|
||||
final Collection<SmartPsiElementPointer<PsiParameter>> unboundedParams = getUnboundedParams(method);
|
||||
final Collection<SmartPsiElementPointer<PsiParameter>> result = new ArrayList<SmartPsiElementPointer<PsiParameter>>(unboundedParams);
|
||||
unboundedParams.clear();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static void processParameter(final Project project,
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Danila Ponomarenko
|
||||
*/
|
||||
public class ReplaceCastAction extends PsiElementBaseIntentionAction {
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Bind Method Parameters to Fields" "true"
|
||||
|
||||
class A{
|
||||
private int myP1;
|
||||
private int myP2;
|
||||
|
||||
void method(int p1, int p2){
|
||||
myP1 = p1;
|
||||
myP2 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// "Bind Constructor Parameters to Fields" "true"
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TestBefore {
|
||||
|
||||
@NotNull
|
||||
private final String myName;
|
||||
@NotNull
|
||||
private final String myName2;
|
||||
|
||||
public TestBefore(@NotNull String name, @NotNull String name2) {
|
||||
super();
|
||||
myName = name;
|
||||
myName2 = name2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// "Bind Constructor Parameters to Fields" "true"
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TestBefore {
|
||||
|
||||
@Nullable
|
||||
private final String myName;
|
||||
@Nullable
|
||||
private final String myName2;
|
||||
|
||||
public TestBefore(@Nullable String name, @Nullable String name2) {
|
||||
super();
|
||||
myName = name;
|
||||
myName2 = name2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Bind Constructor Parameters to Fields" "true"
|
||||
|
||||
class Bar {
|
||||
|
||||
private int myi1;
|
||||
private int myi2;
|
||||
private final int myI1;
|
||||
private final int myI2;
|
||||
private final String myI3;
|
||||
|
||||
Bar(int i1, int i2, String i3) {
|
||||
myI1 = i1;
|
||||
myI2 = i2;
|
||||
myI3 = i3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Bind Method Parameters to Fields" "true"
|
||||
|
||||
class A{
|
||||
private Object myP1;
|
||||
private Object myP2;
|
||||
|
||||
<T> void f(T p1, T p2){
|
||||
myP1 = p1;
|
||||
myP2 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Bind Method Parameters to Fields" "true"
|
||||
|
||||
class A{
|
||||
private String myP1;
|
||||
private String myP2;
|
||||
|
||||
<T extends String> void f(T p1, T p2){
|
||||
myP1 = p1;
|
||||
myP2 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Bind Method Parameters to Fields" "true"
|
||||
|
||||
class A{
|
||||
void <caret>method(int p1, int p2){
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Bind Method Parameters to Fields" "false"
|
||||
|
||||
class A{
|
||||
private final String myP1;
|
||||
|
||||
void <caret>f(String p1){
|
||||
myP1 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Bind Method Parameters to Fields" "false"
|
||||
|
||||
class A{
|
||||
private final String myP1;
|
||||
private final String myP2;
|
||||
|
||||
void <caret>f(String p1, String p2){
|
||||
myP1 = p1;
|
||||
myP2 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Bind Method Parameters to Fields" "false"
|
||||
|
||||
class A{
|
||||
void <caret>f(){
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Bind Constructor Parameters to Fields" "true"
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TestBefore {
|
||||
|
||||
public TestBefore(@NotNull String name<caret>, @NotNull String name2) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Bind Constructor Parameters to Fields" "true"
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class TestBefore {
|
||||
|
||||
public TestBefore(@Nullable String name<caret>, @Nullable String name2) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Bind Constructor Parameters to Fields" "true"
|
||||
|
||||
class Bar {
|
||||
|
||||
private int myi1;
|
||||
private int myi2;
|
||||
|
||||
Bar(int <caret>i1, int i2, String i3) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Bind Method Parameters to Fields" "true"
|
||||
|
||||
class A{
|
||||
<T> void f(T p<caret>1, T p2){
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Bind Method Parameters to Fields" "true"
|
||||
|
||||
class A{
|
||||
<T extends String> void f(T p<caret>1, T p2){
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
/**
|
||||
* @author Danila Ponomarenko
|
||||
*/
|
||||
public class CreateAssignFieldsFromParametersTest extends LightIntentionActionTestCase {
|
||||
public class BindFieldsFromParametersTest extends LightIntentionActionTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
@@ -41,6 +41,6 @@ public class CreateAssignFieldsFromParametersTest extends LightIntentionActionTe
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/createAssignFieldsFromParameters";
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters";
|
||||
}
|
||||
}
|
||||
@@ -192,8 +192,8 @@ intention.assign.field.from.parameter.text=Assign Parameter to Field ''{0}''
|
||||
intention.assign.field.from.parameter.family=Assign Parameter to Field
|
||||
intention.create.field.from.parameter.text=Create Field for Parameter ''{0}''
|
||||
intention.create.field.from.parameter.family=Create Field for Parameter
|
||||
intention.create.assign.fields.from.parameters.text=Create/Assign Fields from {0} Parameters
|
||||
intention.create.assign.fields.from.parameters.family=Create/Assign Fields from Parameters
|
||||
intention.bind.fields.from.parameters.text=Bind {0} Parameters to Fields
|
||||
intention.bind.fields.from.parameters.family=Bind Parameters to Fields
|
||||
intention.implement.abstract.method.searching.for.descendants.progress=Searching For Descendants...
|
||||
intention.implement.abstract.method.error.no.classes.message=There are no classes found where this method can be implemented
|
||||
intention.implement.abstract.method.error.no.classes.title=No Classes Found
|
||||
@@ -205,6 +205,8 @@ intention.extract.if.condition.family=Extract If Condition
|
||||
intention.underscores.in.literals.family=Underscores in numeric literals
|
||||
intention.remove.literal.underscores=Remove underscores from literal
|
||||
intention.insert.literal.underscores=Insert underscores into literal
|
||||
intention.replace.cast.with.var.text=Replace '{0}' with '{1}'
|
||||
intention.replace.cast.with.var.family=Replace cast with variable
|
||||
|
||||
|
||||
intention.create.test=Create Test
|
||||
|
||||
@@ -588,7 +588,7 @@
|
||||
<category>Declaration</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.intention.impl.CreateAssignFieldsFromParametersAction</className>
|
||||
<className>com.intellij.codeInsight.intention.impl.BindFieldsFromParametersAction</className>
|
||||
<category>Declaration</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
@@ -710,6 +710,13 @@
|
||||
<category>Other</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.intention.impl.ReplaceCastAction</className>
|
||||
<category>Other</category>
|
||||
</intentionAction>
|
||||
|
||||
|
||||
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInspection.concurrencyAnnotations.JCiPOrderEntryFix</className>
|
||||
</intentionAction>
|
||||
|
||||
Reference in New Issue
Block a user