diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index d09db2c778af..280bb00ee066 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -15,7 +15,7 @@ */ package com.intellij.codeInsight.daemon.impl.analysis; -import com.google.common.collect.Lists; +import com.intellij.util.containers.CollectionFactory; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.codeInsight.daemon.impl.HighlightInfo; @@ -53,7 +53,8 @@ public class GenericsHighlightUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil"); private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); - private GenericsHighlightUtil() {} + private GenericsHighlightUtil() { + } public static HighlightInfo checkInferredTypeArguments(PsiMethod genericMethod, PsiMethodCallExpression call, @@ -66,7 +67,7 @@ public class GenericsHighlightUtil { PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); for (PsiClassType type : extendsTypes) { PsiType extendsType = substitutor.substitute(type); - if (substituted instanceof PsiWildcardType && TypeConversionUtil.erasure(extendsType).equals(TypeConversionUtil.erasure(((PsiWildcardType)substituted).getExtendsBound()))){ + if (substituted instanceof PsiWildcardType && TypeConversionUtil.erasure(extendsType).equals(TypeConversionUtil.erasure(((PsiWildcardType)substituted).getExtendsBound()))) { PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound(); if (extendsBound instanceof PsiClassType) { PsiType[] parameters = ((PsiClassType)extendsBound).getParameters(); @@ -148,7 +149,8 @@ public class GenericsHighlightUtil { if (PsiTreeUtil.getParentOfType(referenceParameterList, PsiCall.class) != null && PsiUtil.isLanguageLevel7OrHigher(referenceParameterList)) { description = null; - } else { + } + else { description = JavaErrorMessages.message( "generics.type.or.method.does.not.have.type.parameters", typeParameterListOwnerCategoryDescription(typeParameterListOwner), @@ -157,9 +159,7 @@ public class GenericsHighlightUtil { } } else { - description = JavaErrorMessages.message( - "generics.wrong.number.of.type.arguments", refParametersNum, targetParametersNum - ); + description = JavaErrorMessages.message("generics.wrong.number.of.type.arguments", refParametersNum, targetParametersNum); } if (description != null) { @@ -170,7 +170,10 @@ public class GenericsHighlightUtil { PsiElement variable = pparent.getParent(); if (variable instanceof PsiVariable) { if (targetParametersNum == 0) { - QuickFixAction.registerQuickFixAction(highlightInfo, new RemoveTypeArgumentsFix(variable), null); + QuickFixAction.registerQuickFixAction(highlightInfo, new RemoveTypeArgumentsFix(variable)); + } + if (typeParameterListOwner instanceof PsiClass) { + QuickFixAction.registerQuickFixAction(highlightInfo, new ChangeClassSignatureFromUsageFix((PsiClass)typeParameterListOwner, referenceParameterList)); } VariableParameterizedTypeFix.registerIntentions(highlightInfo, (PsiVariable)variable, referenceParameterList); } @@ -186,10 +189,11 @@ public class GenericsHighlightUtil { final PsiType[] types = inferenceResult.getTypes(); for (int i = 0; i < typeParameters.length; i++) { final PsiType type = types[i]; - final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, type, referenceElements[0]); + final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, type, referenceElements[0]); if (highlightInfo != null) return highlightInfo; } - } else { + } + else { for (int i = 0; i < typeParameters.length; i++) { final PsiTypeElement typeElement = referenceElements[i]; final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, typeElement.getType(), typeElement); @@ -243,9 +247,10 @@ public class GenericsHighlightUtil { final PsiType type, final PsiElement typeElement2Highlight) { final PsiClass referenceClass; - if (type instanceof PsiClassType){ + if (type instanceof PsiClassType) { referenceClass = ((PsiClassType)type).resolve(); - } else { + } + else { referenceClass = null; } final PsiType psiType = substitutor.substitute(classParameter); @@ -314,7 +319,8 @@ public class GenericsHighlightUtil { boundBound = ((PsiWildcardType)bound).isSuper() ? ((PsiWildcardType)bound).getSuperBound() : ((PsiWildcardType)bound).getExtendsBound(); - } else { + } + else { return false; } } @@ -335,10 +341,12 @@ public class GenericsHighlightUtil { ? ((PsiWildcardType)bound).getExtendsBound() : ((PsiWildcardType)bound).getSuperBound(); return !TypeConversionUtil.isAssignable(boundBound, type, allowUncheckedConversion); - } else { + } + else { return true; } - } else { + } + else { return !TypeConversionUtil.isAssignable(bound, type, allowUncheckedConversion); } } @@ -349,7 +357,7 @@ public class GenericsHighlightUtil { final PsiClass classType = ((PsiClassType)type).resolve(); if (classType != null) { for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(classType)) { - allowUncheckedConversions &= parameter.getExtendsListTypes().length == 0; + allowUncheckedConversions &= parameter.getExtendsListTypes().length == 0; } } } @@ -404,13 +412,14 @@ public class GenericsHighlightUtil { IntentionAction fix = QUICK_FIX_FACTORY.createExtendsListFix(aClass, type, false); QuickFixAction.registerQuickFixAction(errorResult, fix, null); } - if (errorResult == null && JavaVersionService.getInstance().isAtLeast(referenceList, JavaSdkVersion.JDK_1_7) && + if (errorResult == null && JavaVersionService.getInstance().isAtLeast(referenceList, JavaSdkVersion.JDK_1_7) && referenceElements.length > 1) { //todo suppress erased methods which come from the same class return checkOverrideEquivalentMethods(aClass); } return errorResult; } + public static HighlightInfo checkInterfaceMultipleInheritance(PsiClass aClass) { if (aClass instanceof PsiTypeParameter) return null; final PsiClassType[] types = aClass.getSuperTypes(); @@ -466,7 +475,7 @@ public class GenericsHighlightUtil { PsiManager manager = aClass.getManager(); Map sameErasureMethods = new THashMap(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); - + for (HierarchicalMethodSignature signature : signaturesWithSupers) { HighlightInfo info = checkSameErasureNotSubSignatureInner(signature, manager, aClass, sameErasureMethods); if (info != null) return info; @@ -529,7 +538,8 @@ public class GenericsHighlightUtil { if (checkEqualsSuper && atLeast17) { if (retErasure1 != null && retErasure2 != null) { differentReturnTypeErasure = !TypeConversionUtil.isAssignable(retErasure1, retErasure2); - } else { + } + else { differentReturnTypeErasure = !(retErasure1 == null && retErasure2 == null); } } @@ -565,10 +575,10 @@ public class GenericsHighlightUtil { private static HighlightInfo getSameErasureMessage(final boolean sameClass, final PsiMethod method, final PsiMethod superMethod, TextRange textRange) { - @NonNls final String key = sameClass ? "generics.methods.have.same.erasure" : - method.hasModifierProperty(PsiModifier.STATIC) ? - "generics.methods.have.same.erasure.hide" : - "generics.methods.have.same.erasure.override"; + @NonNls final String key = sameClass ? "generics.methods.have.same.erasure" : + method.hasModifierProperty(PsiModifier.STATIC) ? + "generics.methods.have.same.erasure.hide" : + "generics.methods.have.same.erasure.override"; String description = JavaErrorMessages.message(key, HighlightMethodUtil.createClashMethodMessage(method, superMethod, !sameClass)); return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, description); } @@ -650,7 +660,8 @@ public class GenericsHighlightUtil { if (isRawToGeneric(lType, type)) return true; } return false; - } else if (lType instanceof PsiIntersectionType) { + } + else if (lType instanceof PsiIntersectionType) { for (PsiType type : ((PsiIntersectionType)lType).getConjuncts()) { if (isRawToGeneric(type, rType)) return true; } @@ -672,7 +683,9 @@ public class GenericsHighlightUtil { PsiSubstitutor rSubstitutor = rResolveResult.getSubstitutor(); if (lClass == null || rClass == null) return false; if (lClass instanceof PsiTypeParameter && - !InheritanceUtil.isInheritorOrSelf(rClass, lClass, true)) return true; + !InheritanceUtil.isInheritorOrSelf(rClass, lClass, true)) { + return true; + } if (!lClass.getManager().areElementsEquivalent(lClass, rClass)) { if (lClass.isInheritor(rClass, true)) { @@ -698,7 +711,7 @@ public class GenericsHighlightUtil { PsiType rTypeArg = rSubstitutor.substituteWithBoundsPromotion(rParameter); if (lTypeArg == null) continue; if (rTypeArg == null) { - if (lTypeArg instanceof PsiWildcardType && ((PsiWildcardType) lTypeArg).getBound() == null) { + if (lTypeArg instanceof PsiWildcardType && ((PsiWildcardType)lTypeArg).getBound() == null) { continue; } else { @@ -922,7 +935,7 @@ public class GenericsHighlightUtil { for (int i = 0; i < typeParameters.length; i++) { final PsiTypeParameter typeParameter1 = typeParameters[i]; String name1 = typeParameter1.getName(); - for (int j = i+1; j < typeParameters.length; j++) { + for (int j = i + 1; j < typeParameters.length; j++) { final PsiTypeParameter typeParameter2 = typeParameters[j]; String name2 = typeParameter2.getName(); if (Comparing.strEqual(name1, name2)) { @@ -937,7 +950,7 @@ public class GenericsHighlightUtil { @Nullable public static Collection checkCatchParameterIsClass(PsiParameter parameter) { if (!(parameter.getDeclarationScope() instanceof PsiCatchSection)) return null; - final Collection result = Lists.newArrayList(); + final Collection result = CollectionFactory.arrayList(); final List typeElements = PsiUtil.getParameterTypeElements(parameter); for (PsiTypeElement typeElement : typeElements) { @@ -975,12 +988,12 @@ public class GenericsHighlightUtil { return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, JavaErrorMessages.message("illegal.generic.type.for.instanceof")); } } - + final PsiType[] parameters = ref.getTypeParameters(); for (PsiType parameterType : parameters) { if (parameterType != null && !(parameterType instanceof PsiWildcardType && ((PsiWildcardType)parameterType).getBound() == null)) { - return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, JavaErrorMessages.message("illegal.generic.type.for.instanceof")); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, JavaErrorMessages.message("illegal.generic.type.for.instanceof")); } } @@ -1057,7 +1070,6 @@ public class GenericsHighlightUtil { } - LOG.assertTrue(varParameter.isVarArgs()); final PsiEllipsisType ellipsisType = (PsiEllipsisType)varParameter.getType(); final PsiType componentType = ellipsisType.getComponentType(); @@ -1099,14 +1111,15 @@ public class GenericsHighlightUtil { return false; } } - } else if (lastArg instanceof PsiMethodCallExpression) { + } + else if (lastArg instanceof PsiMethodCallExpression) { if (lastArg.getType() instanceof PsiArrayType) { return false; } } } for (int i = parametersCount - 1; i < args.length; i++) { - if (!isReifiableType(resolveResult.getSubstitutor().substitute(args[i].getType()))){ + if (!isReifiableType(resolveResult.getSubstitutor().substitute(args[i].getType()))) { return true; } } @@ -1156,7 +1169,8 @@ public class GenericsHighlightUtil { } static void checkEnumConstantForConstructorProblems(PsiEnumConstant enumConstant, final HighlightInfoHolder holder) { - PsiClass containingClass = enumConstant.getContainingClass(); if (enumConstant.getInitializingClass() == null) { + PsiClass containingClass = enumConstant.getContainingClass(); + if (enumConstant.getInitializingClass() == null) { HighlightInfo highlightInfo = HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, enumConstant.getNameIdentifier()); if (highlightInfo != null) { QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createImplementMethodsFix(enumConstant)); @@ -1233,8 +1247,9 @@ public class GenericsHighlightUtil { PsiElement parent = refParamList.getParent(); if (parent instanceof PsiJavaCodeReferenceElement) { resolveResult = ((PsiJavaCodeReferenceElement)parent).advancedResolve(false); - } else if (parent instanceof PsiCallExpression) { - resolveResult = ((PsiCallExpression)parent).resolveMethodGenerics(); + } + else if (parent instanceof PsiCallExpression) { + resolveResult = ((PsiCallExpression)parent).resolveMethodGenerics(); } if (resolveResult != null) { PsiElement element = resolveResult.getElement(); @@ -1257,12 +1272,13 @@ public class GenericsHighlightUtil { public static HighlightInfo checkCannotInheritFromEnum(PsiClass superClass, PsiElement elementToHighlight) { HighlightInfo errorResult = null; - if (Comparing.strEqual("java.lang.Enum",superClass.getQualifiedName())) { + if (Comparing.strEqual("java.lang.Enum", superClass.getQualifiedName())) { String message = JavaErrorMessages.message("classes.extends.enum"); errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, elementToHighlight, message); } return errorResult; } + public static HighlightInfo checkGenericCannotExtendException(PsiReferenceList list) { PsiElement parent = list.getParent(); if (!(parent instanceof PsiClass)) return null; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeClassSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeClassSignatureFromUsageFix.java new file mode 100644 index 000000000000..333b38594f57 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeClassSignatureFromUsageFix.java @@ -0,0 +1,233 @@ +/* + * 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.daemon.impl.quickfix; + +import com.intellij.codeInsight.CodeInsightUtilBase; +import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInsight.intention.impl.BaseIntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtilBase; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author Danila Ponomarenko + */ +public class ChangeClassSignatureFromUsageFix extends BaseIntentionAction { + private final PsiClass myClass; + private final PsiReferenceParameterList myParameterList; + + public ChangeClassSignatureFromUsageFix(@NotNull PsiClass aClass, + @NotNull PsiReferenceParameterList parameterList) { + myClass = aClass; + myParameterList = parameterList; + } + + @NotNull + @Override + public String getFamilyName() { + return QuickFixBundle.message("change.class.signature.family"); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + if (!myClass.isValid() || !myParameterList.isValid()) { + return false; + } + + if (myClass.getTypeParameters().length >= myParameterList.getTypeArguments().length) { + return false; + } + + final PsiTypeParameterList classTypeParameterList = myClass.getTypeParameterList(); + if (classTypeParameterList == null) { + return false; + } + + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + Map typeParameterBooleanMap = createTypeParameters( + factory, + classTypeParameterList.getTypeParameters(), + myParameterList.getTypeParameterElements() + ); + + if (isAddOneTypeParameter(typeParameterBooleanMap)) { + setText(QuickFixBundle.message("add.type.parameter.text", myClass.getName())); + } + else { + setText(QuickFixBundle.message("change.class.signature.text", myClass.getName(), parametersToSignatureText(typeParameterBooleanMap))); + } + + return true; + } + + private static boolean isAddOneTypeParameter(@NotNull Map map) { + boolean oneParameter = false; + for (Boolean b : map.values()) { + if (b == Boolean.TRUE) { + if (oneParameter) { + return false; + } + oneParameter = true; + } + } + return true; + } + + @NotNull + private static String parametersToSignatureText(@NotNull Map map) { + final StringBuilder result = new StringBuilder("<"); + for (Map.Entry e : map.entrySet()) { + final String text = e.getKey().getText(); + if (e.getValue() == Boolean.TRUE) { + result.append("").append(text).append(""); + } + else { + result.append(text); + } + result.append(", "); + } + + final int lng = result.length(); + result.delete(lng - 2, lng); + + return result.append(">").toString(); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!CodeInsightUtilBase.prepareFileForWrite(file)) return; + + final PsiTypeParameterList classTypeParameterList = myClass.getTypeParameterList(); + if (classTypeParameterList == null) { + return; + } + + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + + final PsiElement newTypeParameterList = classTypeParameterList.replace( + createTypeParameterList( + factory, + classTypeParameterList.getTypeParameters(), + myParameterList.getTypeParameterElements() + ) + ); + + navigateTo(newTypeParameterList); + } + + private static void navigateTo(@NotNull PsiElement element) { + element.getContainingFile().navigate(false); + final Editor editor = PsiUtilBase.findEditor(element); + if (editor == null) { + return; + } + + editor.getCaretModel().moveToOffset(element.getTextRange().getStartOffset()); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + } + + @NotNull + private static PsiTypeParameterList createTypeParameterList(@NotNull PsiElementFactory factory, + @NotNull PsiTypeParameter[] classTypeParameters, + @NotNull PsiTypeElement[] typeElements) { + final PsiTypeParameterList result = factory.createTypeParameterList(); + for (PsiTypeParameter p : createTypeParameters(factory, classTypeParameters, typeElements).keySet()) { + result.add(p); + } + return result; + } + + @NotNull + private static Map createTypeParameters(@NotNull PsiElementFactory factory, + @NotNull PsiTypeParameter[] classTypeParameters, + @NotNull PsiTypeElement[] typeElements) { + final LinkedHashMap result = new LinkedHashMap(); + final TypeParameterNameSuggester suggester = new TypeParameterNameSuggester(classTypeParameters); + + final Queue classTypeParametersQueue = new LinkedList(Arrays.asList(classTypeParameters)); + for (PsiTypeElement typeElement : typeElements) { + if (!classTypeParametersQueue.isEmpty()) { + final PsiTypeParameter typeParameter = classTypeParametersQueue.peek(); + + if (isAssignable(typeParameter, typeElement.getType())) { + result.put(typeParameter, false); + classTypeParametersQueue.poll(); + continue; + } + } + result.put(toTypeParameter(factory, suggester, typeElement), true); + } + return result; + } + + private static boolean isAssignable(@NotNull PsiTypeParameter typeParameter, @NotNull PsiType type) { + for (PsiClassType t : typeParameter.getExtendsListTypes()) { + if (!t.isAssignableFrom(type)) { + return false; + } + } + + return true; + } + + @NotNull + private static PsiTypeParameter toTypeParameter(@NotNull PsiElementFactory factory, + @NotNull TypeParameterNameSuggester suggester, + @NotNull PsiTypeElement typeElement) { + final PsiType type = typeElement.getType(); + + return factory.createTypeParameter(suggester.suggest((PsiClassType)type), PsiClassType.EMPTY_ARRAY); + } + + @Override + public boolean startInWriteAction() { + return true; + } + + + private static class TypeParameterNameSuggester { + private final Set usedNames = new HashSet(); + + public TypeParameterNameSuggester(@NotNull PsiTypeParameter[] typeParameters) { + for (PsiTypeParameter p : typeParameters) { + usedNames.add(p.getName()); + } + } + + @NotNull + private String suggestUnusedName(@NotNull String name) { + String unusedName = name; + int i = 0; + while (true) { + if (usedNames.add(unusedName)) { + return unusedName; + } + unusedName = name + ++i; + } + } + + @NotNull + public String suggest(@NotNull PsiClassType type) { + return suggestUnusedName(type.getClassName().substring(0, 1).toUpperCase()); + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java index 239b5ed5b676..1545bc89a9fc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java @@ -73,7 +73,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction, HighP private final boolean myChangeAllUsages; private final int myMinUsagesNumberToShowDialog; ParameterInfoImpl[] myNewParametersInfo; - private static final Logger LOG = Logger.getInstance("#" + ChangeMethodSignatureFromUsageFix.class.getName()); + private static final Logger LOG = Logger.getInstance(ChangeMethodSignatureFromUsageFix.class); ChangeMethodSignatureFromUsageFix(@NotNull PsiMethod targetMethod, @NotNull PsiExpression[] expressions, diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodArgumentFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodArgumentFix.java index b406860982b6..06a93cda01ce 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodArgumentFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodArgumentFix.java @@ -29,7 +29,7 @@ import org.jetbrains.annotations.NotNull; * @author ven */ public abstract class MethodArgumentFix implements IntentionAction { - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.MethodArgumentFix"); + private static final Logger LOG = Logger.getInstance(MethodArgumentFix.class); protected final PsiExpressionList myArgList; protected final int myIndex; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddAfter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddAfter.java new file mode 100644 index 000000000000..653a3858e4ea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddAfter.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Foo foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddBefore.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddBefore.java new file mode 100644 index 000000000000..640e1e70fd05 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddBefore.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Foo foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddMultiple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddMultiple.java new file mode 100644 index 000000000000..d542d5552f60 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterAddMultiple.java @@ -0,0 +1,8 @@ +// "Change signature of 'Foo' to 'Foo<S, T extends Integer, S1>'" "true" + +class Foo { + + void method() { + Foo foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterInsert.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterInsert.java new file mode 100644 index 000000000000..3fac9cbe526f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterInsert.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Foo foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterNoParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterNoParameters.java new file mode 100644 index 000000000000..2fbf292b3beb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/afterNoParameters.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Foo foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddAfter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddAfter.java new file mode 100644 index 000000000000..c7643553d0e4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddAfter.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Fooring> foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddBefore.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddBefore.java new file mode 100644 index 000000000000..af8a9c4de881 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddBefore.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Fooring, Integer> foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddMultiple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddMultiple.java new file mode 100644 index 000000000000..18619bfbd3bc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeAddMultiple.java @@ -0,0 +1,8 @@ +// "Change signature of 'Foo' to 'Foo<S, T extends Integer, S1>'" "true" + +class Foo { + + void method() { + Fooring> foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeInsert.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeInsert.java new file mode 100644 index 000000000000..920f8754683a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeInsert.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Fooring, Integer> foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeNoParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeNoParameters.java new file mode 100644 index 000000000000..d6dfb9b2d112 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage/beforeNoParameters.java @@ -0,0 +1,8 @@ +// "Add type parameter to 'Foo'" "true" + +class Foo { + + void method() { + Fooring> foo = new Foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeClassSignatureFromUsageTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeClassSignatureFromUsageTest.java new file mode 100644 index 000000000000..15d4dd2faccb --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeClassSignatureFromUsageTest.java @@ -0,0 +1,29 @@ +/* + * 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.daemon.quickFix; + +/** + * @author Danila Ponomarenko + */ +public class ChangeClassSignatureFromUsageTest extends LightQuickFix15TestCase { + public void test() throws Exception { doAllTests(); } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/changeClassSignatureFromUsage"; + } +} + diff --git a/resources-en/src/messages/QuickFixBundle.properties b/resources-en/src/messages/QuickFixBundle.properties index 447464101eda..8317d3516077 100644 --- a/resources-en/src/messages/QuickFixBundle.properties +++ b/resources-en/src/messages/QuickFixBundle.properties @@ -35,6 +35,10 @@ cast.single.parameter.text=Cast parameter to ''{0}'' add.type.arguments.text=Add explicit type arguments to {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} argument add.type.arguments.single.argument.text=Add explicit type arguments +change.class.signature.text=Change signature of ''{0}'' to ''{0}{1}'' +add.type.parameter.text=Add type parameter to ''{0}'' +change.class.signature.family=Change class signature + uidesigner.change.bound.field.type=Change bound field type cannot.change.field.exception=Cannot change field ''{0}'' type.\nReason: {1}