mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
add explicit type parameters available for conditional expr (IDEA-1179)
This commit is contained in:
@@ -490,6 +490,7 @@ public class HighlightUtil {
|
||||
}
|
||||
if (expression != null && lType != null) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new WrapExpressionFix(lType, expression));
|
||||
AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType);
|
||||
}
|
||||
ChangeNewOperatorTypeFix.register(highlightInfo, expression, lType);
|
||||
return highlightInfo;
|
||||
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 2/17/12
|
||||
*/
|
||||
public class AddTypeArgumentsConditionalFix implements IntentionAction {
|
||||
private static final Logger LOG = Logger.getInstance("#" + AddTypeArgumentsConditionalFix.class.getName());
|
||||
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
private final PsiMethodCallExpression myExpression;
|
||||
private final PsiMethod myMethod;
|
||||
|
||||
public AddTypeArgumentsConditionalFix(PsiSubstitutor substitutor, PsiMethodCallExpression expression, PsiMethod method) {
|
||||
mySubstitutor = substitutor;
|
||||
myExpression = expression;
|
||||
myMethod = method;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Add explicit type arguments";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
if (mySubstitutor.isValid() && myExpression.isValid() && myMethod.isValid()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final PsiTypeParameter[] typeParameters = myMethod.getTypeParameters();
|
||||
final String typeArguments = "<" + StringUtil.join(typeParameters, new Function<PsiTypeParameter, String>() {
|
||||
@Override
|
||||
public String fun(PsiTypeParameter parameter) {
|
||||
final PsiType substituteTypeParam = mySubstitutor.substitute(parameter);
|
||||
LOG.assertTrue(substituteTypeParam != null);
|
||||
return substituteTypeParam.getCanonicalText();
|
||||
}
|
||||
}, ", ") + ">";
|
||||
final PsiExpression expression = myExpression.getMethodExpression().getQualifierExpression();
|
||||
String withTypeArgsText;
|
||||
if (expression != null) {
|
||||
withTypeArgsText = expression.getText();
|
||||
}
|
||||
else {
|
||||
if (RefactoringUtil.isInStaticContext(myExpression, null) || myMethod.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass aClass = myMethod.getContainingClass();
|
||||
LOG.assertTrue(aClass != null);
|
||||
withTypeArgsText = aClass.getQualifiedName();
|
||||
}
|
||||
else {
|
||||
withTypeArgsText = "this";
|
||||
}
|
||||
}
|
||||
withTypeArgsText += "." + typeArguments + myExpression.getMethodExpression().getReferenceName();
|
||||
final PsiExpression withTypeArgs = JavaPsiFacade.getElementFactory(project).createExpressionFromText(withTypeArgsText + myExpression.getArgumentList().getText(), myExpression);
|
||||
myExpression.replace(withTypeArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void register(HighlightInfo highlightInfo, PsiExpression expression, PsiType lType) {
|
||||
if (expression instanceof PsiConditionalExpression) {
|
||||
final PsiExpression thenExpression = ((PsiConditionalExpression)expression).getThenExpression();
|
||||
final PsiExpression elseExpression = ((PsiConditionalExpression)expression).getElseExpression();
|
||||
if (thenExpression != null && elseExpression != null) {
|
||||
final PsiType thenType = thenExpression.getType();
|
||||
final PsiType elseType = elseExpression.getType();
|
||||
if (thenType != null && elseType != null) {
|
||||
final boolean thenAssignable = TypeConversionUtil.isAssignable(lType, thenType);
|
||||
final boolean elseAssignable = TypeConversionUtil.isAssignable(lType, elseType);
|
||||
if (!thenAssignable && thenExpression instanceof PsiMethodCallExpression) {
|
||||
inferTypeArgs(highlightInfo, lType, thenExpression);
|
||||
}
|
||||
if (!elseAssignable && elseExpression instanceof PsiMethodCallExpression) {
|
||||
inferTypeArgs(highlightInfo, lType, elseExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void inferTypeArgs(HighlightInfo highlightInfo, PsiType lType, PsiExpression thenExpression) {
|
||||
final JavaResolveResult result = ((PsiMethodCallExpression)thenExpression).resolveMethodGenerics();
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (method != null) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
if (returnType != null && aClass != null && aClass.getQualifiedName() != null) {
|
||||
final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject());
|
||||
final PsiDeclarationStatement variableDeclarationStatement =
|
||||
javaPsiFacade.getElementFactory().createVariableDeclarationStatement("xxx", lType, thenExpression);
|
||||
final PsiExpression initializer =
|
||||
((PsiLocalVariable)variableDeclarationStatement.getDeclaredElements()[0]).getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
|
||||
final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper()
|
||||
.inferTypeArguments(method.getTypeParameters(), method.getParameterList().getParameters(),
|
||||
((PsiMethodCallExpression)thenExpression).getArgumentList().getExpressions(), PsiSubstitutor.EMPTY,
|
||||
initializer, DefaultParameterTypeInferencePolicy.INSTANCE);
|
||||
PsiType substitutedType = substitutor.substitute(returnType);
|
||||
if (substitutedType != null && TypeConversionUtil.isAssignable(lType, substitutedType)) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo,
|
||||
thenExpression.getTextRange(),
|
||||
new AddTypeArgumentsConditionalFix(substitutor, (PsiMethodCallExpression)thenExpression, method), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ public class RefactoringUtil {
|
||||
return Comparing.equal(virtualFile, sourceRootForFile);
|
||||
}
|
||||
|
||||
public static boolean isInStaticContext(PsiElement element, final PsiClass aClass) {
|
||||
public static boolean isInStaticContext(PsiElement element, @Nullable final PsiClass aClass) {
|
||||
return PsiUtil.getEnclosingStaticElement(element, aClass) != null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user