mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
wrap with optional IDEA-122553
This commit is contained in:
@@ -270,4 +270,9 @@ public abstract class QuickFixFactory {
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createWrapLongWithMathToIntExactFix(@Nullable PsiType type, @NotNull PsiExpression expression);
|
||||
|
||||
@NotNull
|
||||
public IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
}
|
||||
|
||||
+3
@@ -607,6 +607,7 @@ public class HighlightMethodUtil {
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
|
||||
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
|
||||
registerChangeParameterClassFix(methodCall, list, info);
|
||||
@@ -694,6 +695,7 @@ public class HighlightMethodUtil {
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
|
||||
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
|
||||
registerChangeParameterClassFix(methodCall, list, info);
|
||||
@@ -729,6 +731,7 @@ public class HighlightMethodUtil {
|
||||
AddTypeArgumentsFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, highlightInfo);
|
||||
registerChangeMethodSignatureFromUsageIntentions(methodCandidates, list, highlightInfo, fixRange);
|
||||
RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, highlightInfo, fixRange);
|
||||
|
||||
+1
@@ -568,6 +568,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
if (expression != null) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapLongWithMathToIntExactFix(lType, expression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapWithOptionalFix(lType, expression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapExpressionFix(lType, expression));
|
||||
AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType);
|
||||
}
|
||||
|
||||
+4
-2
@@ -91,8 +91,10 @@ public abstract class ArgumentFixerActionFactory {
|
||||
if (!GenericsUtil.isFromExternalTypeLanguage(parameterType)) continue;
|
||||
if (suggestedCasts.contains(parameterType.getCanonicalText())) continue;
|
||||
if (exprType instanceof PsiPrimitiveType && parameterType instanceof PsiClassType) {
|
||||
parameterType = PsiPrimitiveType.getUnboxedType(parameterType);
|
||||
if (parameterType == null) continue;
|
||||
PsiType unboxedParameterType = PsiPrimitiveType.getUnboxedType(parameterType);
|
||||
if (unboxedParameterType != null) {
|
||||
parameterType = unboxedParameterType;
|
||||
}
|
||||
}
|
||||
// strict compare since even widening cast may help
|
||||
if (Comparing.equal(exprType, parameterType)) continue;
|
||||
|
||||
+1
@@ -45,5 +45,6 @@ public class ConstructorParametersFixer {
|
||||
AddTypeArgumentsFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
}
|
||||
}
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* 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.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
|
||||
import com.intellij.codeInspection.dataFlow.Nullness;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class WrapObjectWithOptionalOfNullableFix extends MethodArgumentFix implements HighPriorityAction {
|
||||
private static final Logger LOG = Logger.getInstance(WrapObjectWithOptionalOfNullableFix.class);
|
||||
|
||||
public static final ArgumentFixerActionFactory REGISTAR = new MyFixerActionFactory();
|
||||
|
||||
protected WrapObjectWithOptionalOfNullableFix(final @NotNull PsiExpressionList list,
|
||||
final int i,
|
||||
final @NotNull PsiType toType,
|
||||
final @NotNull ArgumentFixerActionFactory fixerActionFactory) {
|
||||
super(list, i, toType, fixerActionFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
if (myArgList.getExpressions().length == 1) {
|
||||
return QuickFixBundle.message("wrap.with.optional.single.parameter.text");
|
||||
}
|
||||
else {
|
||||
return QuickFixBundle.message("wrap.with.optional.parameter.text", myIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return PsiUtil.isLanguageLevel8OrHigher(file) && super.isAvailable(project, editor, file);
|
||||
}
|
||||
|
||||
public static class MyIntentionAction extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
|
||||
@Nullable private final PsiType myType;
|
||||
|
||||
protected MyIntentionAction(@NotNull PsiExpression element, @Nullable PsiType type) {
|
||||
super(element);
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("wrap.with.optional.single.parameter.text");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable("is null when called from inspection") Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
startElement.replace(getModifiedExpression((PsiExpression)getStartElement()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
return startElement.isValid() &&
|
||||
startElement.getManager().isInProject(startElement) &&
|
||||
PsiUtil.isLanguageLevel8OrHigher(startElement) && areConvertible(((PsiExpression) startElement).getType(), myType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
}
|
||||
|
||||
public static IntentionAction createFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
class MyFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
|
||||
protected MyFix(@Nullable PsiElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("wrap.with.optional.single.parameter.text");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable("is null when called from inspection") Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
startElement.replace(getModifiedExpression((PsiExpression)getStartElement()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
return startElement.isValid() &&
|
||||
startElement.getManager().isInProject(startElement) &&
|
||||
PsiUtil.isLanguageLevel8OrHigher(startElement) && areConvertible(expression.getType(), type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
}
|
||||
return new MyFix(expression);
|
||||
}
|
||||
|
||||
public static class MyFixerActionFactory extends ArgumentFixerActionFactory {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiExpression getModifiedArgument(final PsiExpression expression, final PsiType toType) throws IncorrectOperationException {
|
||||
return getModifiedExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areTypesConvertible(final PsiType exprType, final PsiType parameterType, final PsiElement context) {
|
||||
return parameterType.isConvertibleFrom(exprType) || areConvertible(exprType, parameterType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) {
|
||||
return new WrapObjectWithOptionalOfNullableFix(list, i, toType, this);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areConvertible(@Nullable PsiType exprType, @Nullable PsiType parameterType) {
|
||||
if (exprType == null || !(parameterType instanceof PsiClassType)) {
|
||||
return false;
|
||||
}
|
||||
final PsiClassType.ClassResolveResult resolve = ((PsiClassType)parameterType).resolveGenerics();
|
||||
final PsiClass resolvedClass = resolve.getElement();
|
||||
if (resolvedClass == null || !CommonClassNames.JAVA_UTIL_OPTIONAL.equals(resolvedClass.getQualifiedName())) return false;
|
||||
|
||||
final Collection<PsiType> values = resolve.getSubstitutor().getSubstitutionMap().values();
|
||||
if (values.size() == 0) return true;
|
||||
if (values.size() > 1) return false;
|
||||
final PsiType optionalTypeParameter = ContainerUtil.getFirstItem(values);
|
||||
if (optionalTypeParameter == null) return false;
|
||||
return TypeConversionUtil.isAssignable(optionalTypeParameter, exprType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiExpression getModifiedExpression(PsiExpression expression) {
|
||||
final Project project = expression.getProject();
|
||||
PsiModifierListOwner toCheckNullability = null;
|
||||
if (expression instanceof PsiMethodCallExpression) {
|
||||
toCheckNullability = ((PsiMethodCallExpression)expression).resolveMethod();
|
||||
}
|
||||
else if (expression instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolved = ((PsiReferenceExpression)expression).resolve();
|
||||
if (resolved instanceof PsiModifierListOwner) {
|
||||
toCheckNullability = (PsiModifierListOwner)resolved;
|
||||
}
|
||||
}
|
||||
final Nullness nullability = toCheckNullability == null ? Nullness.NOT_NULL : DfaPsiUtil
|
||||
.getElementNullability(expression.getType(), toCheckNullability);
|
||||
String methodName = nullability == Nullness.NOT_NULL ? "of" : "ofNullable";
|
||||
final String newExpressionText = CommonClassNames.JAVA_UTIL_OPTIONAL + "." + methodName + "(" + expression.getText() + ")";
|
||||
return JavaPsiFacade.getElementFactory(project).createExpressionFromText(newExpressionText, expression);
|
||||
}
|
||||
}
|
||||
+6
@@ -620,4 +620,10 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
|
||||
public IntentionAction createWrapLongWithMathToIntExactFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -780,6 +780,12 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
return new WrapLongWithMathToIntExactFix(type, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return WrapObjectWithOptionalOfNullableFix.createFix(type, expression);
|
||||
}
|
||||
|
||||
private static boolean timeToOptimizeImports(@NotNull PsiFile file) {
|
||||
if (!CodeInsightSettings.getInstance().OPTIMIZE_IMPORTS_ON_THE_FLY) return false;
|
||||
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'java.util.Optional'" "true"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m() {
|
||||
Optional<String> o = Optional.of("some string value");
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap 2nd parameter using 'java.util.Optional'" "true"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m() {
|
||||
long ll = 10;
|
||||
f(10, Optional.ofNullable(ll), 10);
|
||||
}
|
||||
|
||||
|
||||
void f(long j, Optional<Number> o, int i) {
|
||||
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Wrap using 'java.util.Optional'" "true"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m(String ss) {
|
||||
f(Optional.ofNullable(ss));
|
||||
}
|
||||
|
||||
|
||||
void f(Optional<String> o) {
|
||||
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'java.util.Optional'" "true"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m() {
|
||||
Optional<String> o = "some <caret>string value";
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Wrap using 'java.util.Optional'" "false"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m(String ss) {
|
||||
f(ss);
|
||||
}
|
||||
|
||||
|
||||
void f(Optional<Long> o) {
|
||||
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Wrap 2nd parameter using 'java.util.Optional'" "true"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m() {
|
||||
long ll = 10;
|
||||
f(10, l<caret>l, 10);
|
||||
}
|
||||
|
||||
|
||||
void f(long j, Optional<Number> o, int i) {
|
||||
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Wrap using 'java.util.Optional'" "true"
|
||||
import java.util.Optional;
|
||||
|
||||
public class Test {
|
||||
|
||||
void m(String ss) {
|
||||
f(s<caret>s);
|
||||
}
|
||||
|
||||
|
||||
void f(Optional<String> o) {
|
||||
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.daemon.quickFix;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class WrapObjectWithOptionalFixTest extends LightQuickFixParameterizedTestCase {
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/wrapObjectWithOptional";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.ui.treeStructure.treetable;
|
||||
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
@@ -52,7 +53,6 @@ public class TreeTable extends JBTable {
|
||||
|
||||
public TreeTable(TreeTableModel treeTableModel) {
|
||||
super();
|
||||
|
||||
setModel(treeTableModel);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class TreeTable extends JBTable {
|
||||
|
||||
// And update the height of the trees row to match that of the table.
|
||||
if (myTree.getRowHeight() < 1) {
|
||||
setRowHeight(18); // Metal looks better like this.
|
||||
setRowHeight(JBUI.scale(18)); // Metal looks better like this.
|
||||
}
|
||||
else {
|
||||
setRowHeight(getRowHeight());
|
||||
|
||||
@@ -282,4 +282,7 @@ add.exception.from.field.initializer.to.constructor.throws.text=Add exception to
|
||||
add.exception.from.field.initializer.to.constructor.throws.family.text=Add exception to class constructors signature
|
||||
java.8.collections.api.inspection.description=If statement could be replaced with single method
|
||||
java.8.collections.api.inspection.fix.family.name=Replace with single method call
|
||||
java.8.collections.api.inspection.fix.text=Replace with ''{0}'' method call
|
||||
java.8.collections.api.inspection.fix.text=Replace with ''{0}'' method call
|
||||
|
||||
wrap.with.optional.parameter.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''java.util.Optional''
|
||||
wrap.with.optional.single.parameter.text=Wrap using 'java.util.Optional'
|
||||
Reference in New Issue
Block a user