@NotNull
public abstract IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall);
+
+ @NotNull
+ public abstract IntentionAction createWrapLongWithMathToIntExactFix(@NotNull PsiExpression expression);
}
TextRange fixRange = getFixRange(elementToHighlight);
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
+ WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
registerChangeParameterClassFix(methodCall, list, info);
TextRange fixRange = getFixRange(elementToHighlight);
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
+ WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
registerChangeParameterClassFix(methodCall, list, info);
PermuteArgumentsFix.registerFix(highlightInfo, methodCall, methodCandidates, fixRange);
AddTypeArgumentsFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
+ WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, highlightInfo);
registerChangeMethodSignatureFromUsageIntentions(methodCandidates, list, highlightInfo, fixRange);
RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, highlightInfo, fixRange);
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createAddTypeCastFix(lType, expression));
}
if (expression != null) {
+ if (PsiType.INT.equals(lType) && rType != null && (PsiType.LONG.equals(rType) || PsiType.LONG.getBoxedTypeName().equals(rType.getCanonicalText(false)))) {
+ QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapLongWithMathToIntExactFix(expression));
+ }
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapExpressionFix(lType, expression));
AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType);
}
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createConvertSwitchToIfIntention(statement));
if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createAddTypeCastFix(PsiType.INT, expression));
+ if (PsiType.LONG.equals(type)) {
+ QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createWrapLongWithMathToIntExactFix(expression));
+ }
}
if (requiredLevel != null) {
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createIncreaseLanguageLevelFix(requiredLevel));
}
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
AddTypeArgumentsFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
+ WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
+ WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
}
}
--- /dev/null
+/*
+ * Copyright 2000-2015 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.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInsight.intention.HighPriorityAction;
+import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+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.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class WrapLongWithMathToIntExactFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
+ private final static Logger LOG = Logger.getInstance(WrapLongWithMathToIntExactFix.class);
+
+ public final static MyMethodArgumentFixerFactory REGISTAR = new MyMethodArgumentFixerFactory();
+
+ public WrapLongWithMathToIntExactFix(final @NotNull PsiExpression expression) {
+ super(expression);
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return getFamilyName();
+ }
+
+ @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(startElement));
+ }
+
+ @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);
+ }
+
+ @Nls
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return QuickFixBundle.message("wrap.long.with.math.to.int.text");
+ }
+
+ private static PsiElement getModifiedExpression(PsiElement expression) {
+ return JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText("java.lang.Math.toIntExact(" + expression.getText() + ")", expression);
+ }
+
+ private static class MyMethodArgumentFix extends MethodArgumentFix implements HighPriorityAction {
+
+ protected MyMethodArgumentFix(@NotNull PsiExpressionList list,
+ int i,
+ @NotNull PsiType toType,
+ @NotNull ArgumentFixerActionFactory fixerActionFactory) {
+ super(list, i, toType, fixerActionFactory);
+ }
+
+ @Nls
+ @NotNull
+ @Override
+ public String getText() {
+ return myArgList.getExpressions().length == 1
+ ? QuickFixBundle.message("wrap.long.with.math.to.int.parameter.single.text")
+ : QuickFixBundle.message("wrap.long.with.math.to.int.parameter.multiple.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 MyMethodArgumentFixerFactory extends ArgumentFixerActionFactory {
+ @Nullable
+ @Override
+ protected PsiExpression getModifiedArgument(final PsiExpression expression, final PsiType toType) throws IncorrectOperationException {
+ LOG.assertTrue(PsiType.INT.equals(toType));
+ return (PsiExpression)getModifiedExpression(expression);
+ }
+
+ @Override
+ public boolean areTypesConvertible(final PsiType exprType, final PsiType parameterType, final PsiElement context) {
+ return parameterType.isConvertibleFrom(exprType) || (PsiType.INT.equals(parameterType) && PsiType.LONG.equals(exprType));
+ }
+
+ @Override
+ public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) {
+ return new MyMethodArgumentFix(list, i, toType, this);
+ }
+ }
+}
public IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall) {
return QuickFixes.EMPTY_FIX;
}
+
+ @NotNull
+ @Override
+ public IntentionAction createWrapLongWithMathToIntExactFix(@NotNull PsiExpression expression) {
+ return QuickFixes.EMPTY_FIX;
+ }
}
return new AddMethodQualifierFix(methodCall);
}
+ @NotNull
+ @Override
+ public IntentionAction createWrapLongWithMathToIntExactFix(@NotNull PsiExpression expression) {
+ return new WrapLongWithMathToIntExactFix(expression);
+ }
+
private static boolean timeToOptimizeImports(@NotNull PsiFile file) {
if (!CodeInsightSettings.getInstance().OPTIMIZE_IMPORTS_ON_THE_FLY) return false;
--- /dev/null
+// "Wrap using 'Math.toIntExact()'" "true"
+public class Test {
+
+ void m(long l) {
+
+ int i = 10;
+ i = Math.toIntExact(l);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+// "Wrap 2nd parameter using 'Math.toIntExact()'" "true"
+public class Test {
+
+ void longMethod(int k, int thisIsInt) {
+
+ }
+
+ void m(long ll) {
+ longMethod(13, Math.toIntExact(ll));
+ }
+
+}
--- /dev/null
+// "Wrap parameter using 'Math.toIntExact()'" "true"
+
+public class Test {
+ void m(int i) {
+
+ }
+
+ void method() {
+ m(Math.toIntExact(10L));
+ }
+
+}
--- /dev/null
+// "Wrap using 'Math.toIntExact()'" "true"
+public class Test {
+
+ void m() {
+
+ int i = Math.toIntExact(Long.valueOf(123));
+
+ }
+
+}
--- /dev/null
+// "Wrap using 'Math.toIntExact()'" "true"
+public class Test {
+
+ void m(long l) {
+
+ int i = 10;
+ i = l<caret>;
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+// "Wrap 2nd parameter using 'Math.toIntExact()'" "true"
+public class Test {
+
+ void longMethod(int k, int thisIsInt) {
+
+ }
+
+ void m(long ll) {
+ longMethod(13, l<caret>l);
+ }
+
+}
--- /dev/null
+// "Wrap parameter using 'Math.toIntExact()'" "true"
+
+public class Test {
+ void m(int i) {
+
+ }
+
+ void method() {
+ m(10<caret>L);
+ }
+
+}
--- /dev/null
+// "Wrap using 'Math.toIntExact()'" "true"
+public class Test {
+
+ void m() {
+
+ int i = Long.valu<caret>eOf(123);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2000-2015 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 WrapLongWithMathToIntExactFixTest extends LightQuickFixParameterizedTestCase {
+ public void test() throws Exception {
+ doAllTests();
+ }
+
+ @Override
+ protected String getBasePath() {
+ return "/codeInsight/daemonCodeAnalyzer/quickFix/wrapLongWithMathToIntExact";
+ }
+
+ @Override
+ protected Sdk getProjectJDK() {
+ return IdeaTestUtil.getMockJdk18();
+ }
+}
collection.addall.can.be.replaced.with.constructor.fix.options.title=Classes to check
collection.addall.can.be.replaced.with.constructor.fix.description='addAll()' method can be replaced with parametrized constructor
-collection.addall.can.be.replaced.with.constructor.fix.title=Replace 'addAll()' method with parametrized constructor call
\ No newline at end of file
+collection.addall.can.be.replaced.with.constructor.fix.title=Replace 'addAll()' method with parametrized constructor call
+
+wrap.long.with.math.to.int.text=Wrap using 'Math.toIntExact()'
+wrap.long.with.math.to.int.parameter.single.text=Wrap parameter using 'Math.toIntExact()'
+wrap.long.with.math.to.int.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''Math.toIntExact()''
\ No newline at end of file