mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 05:21:29 +07:00
inspection/intention to collapse/expand lambda body (IDEA-90827)
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class RedundantLambdaCodeBlockInspection extends BaseJavaLocalInspectionTool {
|
||||
public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaCodeBlockInspection.class.getName());
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.LANGUAGE_LEVEL_SPECIFIC_GROUP_NAME;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Lambda code block can be replaced with expression";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return "CodeBlock2Expr";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new JavaElementVisitor() {
|
||||
@Override
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
super.visitLambdaExpression(expression);
|
||||
final PsiElement body = expression.getBody();
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
|
||||
if (statements.length == 1 && statements[0] instanceof PsiReturnStatement) {
|
||||
final PsiReturnStatement returnStatement = (PsiReturnStatement)statements[0];
|
||||
final PsiExpression returnValue = returnStatement.getReturnValue();
|
||||
if (returnValue != null) {
|
||||
holder.registerProblem(returnStatement.getFirstChild(), "Lambda code block can be replaced with one line expression",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithExprFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class ReplaceWithExprFix implements LocalQuickFix, HighPriorityAction {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Replace with one line expression";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (element != null) {
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
|
||||
if (lambdaExpression != null) {
|
||||
PsiElement body = lambdaExpression.getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
PsiExpression returnValue = ((PsiReturnStatement)((PsiCodeBlock)body).getStatements()[0]).getReturnValue();
|
||||
LOG.assertTrue(returnValue != null);
|
||||
body.replace(returnValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Replace with one line expression" "true"
|
||||
class Test {
|
||||
{
|
||||
Comparable<String> c = (o) -> 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "Replace with one line expression" "true"
|
||||
class Test {
|
||||
{
|
||||
Comparable<String> c = (o) -> {r<caret>eturn 0};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.RedundantLambdaCodeBlockInspection;
|
||||
|
||||
|
||||
public class RedundantLambdaCodeBlockInspectionTest extends LightQuickFixTestCase {
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{
|
||||
new RedundantLambdaCodeBlockInspection(),
|
||||
};
|
||||
}
|
||||
|
||||
public void test() throws Exception { doAllTests(); }
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/lambdaCodeBlock2Expr";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -219,6 +219,11 @@
|
||||
<categoryKey>intention.category.declaration</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>com.siyeh.ipp.types.ExpandOneLineLambda2CodeBlockIntention</className>
|
||||
<categoryKey>intention.category.declaration</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>com.siyeh.ipp.decls.ChangeVariableTypeToRhsTypeIntention</className>
|
||||
<categoryKey>intention.category.declaration</categoryKey>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2011 Bas Leijdekkers
|
||||
*
|
||||
* 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.siyeh.ipp.types;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ExpandOneLineLambda2CodeBlockIntention extends Intention {
|
||||
private static final Logger LOG = Logger.getInstance("#" + ExpandOneLineLambda2CodeBlockIntention.class.getName());
|
||||
@NotNull
|
||||
@Override
|
||||
protected PsiElementPredicate getElementPredicate() {
|
||||
return new LambdaExpressionPredicate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Expand lambda expression body to {...}";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
|
||||
LOG.assertTrue(lambdaExpression != null);
|
||||
final PsiElement body = lambdaExpression.getBody();
|
||||
LOG.assertTrue(body instanceof PsiExpression);
|
||||
String blockText = "{";
|
||||
blockText += ((PsiExpression)body).getType() == PsiType.VOID ? "" : "return ";
|
||||
blockText += body.getText() + ";}";
|
||||
|
||||
final String resultedLambdaText = lambdaExpression.getParameterList().getText() + "->" + blockText;
|
||||
final PsiExpression expressionFromText =
|
||||
JavaPsiFacade.getElementFactory(element.getProject()).createExpressionFromText(resultedLambdaText, lambdaExpression);
|
||||
lambdaExpression.replace(expressionFromText);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class LambdaExpressionPredicate implements PsiElementPredicate {
|
||||
@Override
|
||||
public boolean satisfiedBy(PsiElement element) {
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
|
||||
if (lambdaExpression != null) {
|
||||
return lambdaExpression.getBody() instanceof PsiExpression;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class X {
|
||||
{
|
||||
Comparable c = o -> {return 42;};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class X {
|
||||
{
|
||||
Comparable c = o -> <spot>42</spot>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention converts lambda's expression body to code block
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
class X {
|
||||
{
|
||||
Comparable<String> c = o <caret>-> 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class X {
|
||||
{
|
||||
Comparable<String> c = o -> {
|
||||
return 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.siyeh.ipp.types;
|
||||
|
||||
import com.siyeh.ipp.IPPTestCase;
|
||||
|
||||
public class ExpandOneLineLambda2CodeBlockIntentionTest extends IPPTestCase {
|
||||
|
||||
public void testSimple() {
|
||||
doTest();
|
||||
}
|
||||
@Override
|
||||
protected String getIntentionName() {
|
||||
return "Expand lambda expression body to {...}";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRelativePath() {
|
||||
return "types/expr2block";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports lambda expressions with code block bodies when expression-style bodies can be used
|
||||
</body>
|
||||
</html>
|
||||
@@ -536,6 +536,9 @@
|
||||
<localInspection language="JAVA" shortName="Convert2Lambda" displayName="Anonymous type can be replaced with lambda"
|
||||
groupName="Java language level migration aids" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.AnonymousCanBeLambdaInspection" />
|
||||
<localInspection language="JAVA" shortName="CodeBlock2Expr" displayName="Lambda code block can be replaced with expression"
|
||||
groupName="Java language level migration aids" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.RedundantLambdaCodeBlockInspection" />
|
||||
<localInspection language="JAVA" shortName="RedundantLambdaParameterType" displayName="Redundant lambda parameter type"
|
||||
groupName="Java language level migration aids" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.RedundantLambdaParameterTypeInspection" />
|
||||
|
||||
Reference in New Issue
Block a user