Issue #2603: add allowEmptyLambda parameter to WhitespaceAroundCheck
This commit is contained in:
parent
6127a44e20
commit
02bc165a36
|
|
@ -98,7 +98,7 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
* </pre>
|
||||
*
|
||||
* <p>In addition, this check can be configured to allow empty methods, types,
|
||||
* for, while, do-while loops and constructor bodies.
|
||||
* for, while, do-while loops, lambdas and constructor bodies.
|
||||
* For example:
|
||||
*
|
||||
* <pre>{@code
|
||||
|
|
@ -111,6 +111,7 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
* while (i = 1) {} // empty while loop
|
||||
* for (int i = 1; i > 1; i++) {} // empty for loop
|
||||
* do {} while (i = 1); // empty do-while loop
|
||||
* Runnable noop = () -> {}; // empty lambda
|
||||
* public @interface Beta {} // empty annotation type
|
||||
* }</pre>
|
||||
*
|
||||
|
|
@ -130,6 +131,10 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
*
|
||||
* <pre> <property name="allowEmptyLoops" value="true" /></pre>
|
||||
*
|
||||
* <p>To configure the check to allow empty lambdas blocks use
|
||||
*
|
||||
* <pre> <property name="allowEmptyLambdas" value="true" /></pre>
|
||||
*
|
||||
* <p>Also, this check can be configured to ignore the colon in an enhanced for
|
||||
* loop. The colon in an enhanced for loop is ignored by default
|
||||
*
|
||||
|
|
@ -163,6 +168,8 @@ public class WhitespaceAroundCheck extends Check {
|
|||
private boolean allowEmptyTypes;
|
||||
/** Whether or not empty loops are allowed. */
|
||||
private boolean allowEmptyLoops;
|
||||
/** Whether or not empty lambda blocks are allowed. */
|
||||
private boolean allowEmptyLambdas;
|
||||
/** Whether or not to ignore a colon in a enhanced for loop. */
|
||||
private boolean ignoreEnhancedForColon = true;
|
||||
|
||||
|
|
@ -327,6 +334,14 @@ public class WhitespaceAroundCheck extends Check {
|
|||
allowEmptyLoops = allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not empty lambdas bodies are allowed.
|
||||
* @param allow {@code true} to allow empty lambda expressions.
|
||||
*/
|
||||
public void setAllowEmptyLambdas(boolean allow) {
|
||||
allowEmptyLambdas = allow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitToken(DetailAST ast) {
|
||||
final int currentType = ast.getType();
|
||||
|
|
@ -408,7 +423,8 @@ public class WhitespaceAroundCheck extends Check {
|
|||
private boolean isEmptyBlock(DetailAST ast, int parentType) {
|
||||
return isEmptyMethodBlock(ast, parentType)
|
||||
|| isEmptyCtorBlock(ast, parentType)
|
||||
|| isEmptyLoop(ast, parentType);
|
||||
|| isEmptyLoop(ast, parentType)
|
||||
|| isEmptyLambda(ast, parentType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -429,8 +445,10 @@ public class WhitespaceAroundCheck extends Check {
|
|||
private static boolean isEmptyBlock(DetailAST ast, int parentType, int match) {
|
||||
final int type = ast.getType();
|
||||
if (type == TokenTypes.RCURLY) {
|
||||
final DetailAST parent = ast.getParent();
|
||||
final DetailAST grandParent = ast.getParent().getParent();
|
||||
return parentType == TokenTypes.SLIST
|
||||
&& parent.getFirstChild().getType() == TokenTypes.RCURLY
|
||||
&& grandParent.getType() == match;
|
||||
}
|
||||
|
||||
|
|
@ -518,6 +536,18 @@ public class WhitespaceAroundCheck extends Check {
|
|||
parentType, TokenTypes.LITERAL_DO));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the given {@code DetailAST} is part of an allowed empty
|
||||
* lambda block.
|
||||
* @param ast the {@code DetailAST} to test.
|
||||
* @param parentType the token type of {@code ast}'s parent.
|
||||
* @return {@code true} if {@code ast} makes up part of an
|
||||
* allowed empty lambda block.
|
||||
*/
|
||||
private boolean isEmptyLambda(DetailAST ast, int parentType) {
|
||||
return allowEmptyLambdas && isEmptyBlock(ast, parentType, TokenTypes.LAMBDA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the given {@code DetailAST} is part of an empty block.
|
||||
* An example empty block might look like the following
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ public class WhitespaceAroundCheckTest
|
|||
+ "whitespace" + File.separator + filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNonCompilablePath(String filename) throws IOException {
|
||||
return super.getNonCompilablePath("checks" + File.separator
|
||||
+ "whitespace" + File.separator + filename);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRequiredTokens() {
|
||||
final WhitespaceAroundCheck checkObj = new WhitespaceAroundCheck();
|
||||
|
|
@ -330,4 +336,31 @@ public class WhitespaceAroundCheckTest
|
|||
verify(checkConfig, getPath("InputAllowEmptyTypesAndNonEmptyClasses.java"),
|
||||
expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotAllowEmptyLambdaExpressionsByDefault() throws Exception {
|
||||
final String[] expected = {
|
||||
"7:28: " + getCheckMessage(WS_NOT_FOLLOWED, "{"),
|
||||
"7:28: " + getCheckMessage(WS_NOT_PRECEDED, "}"),
|
||||
"12:29: " + getCheckMessage(WS_NOT_FOLLOWED, "{"),
|
||||
"12:30: " + getCheckMessage(WS_NOT_PRECEDED, "}"),
|
||||
"13:29: " + getCheckMessage(WS_NOT_FOLLOWED, "{"),
|
||||
"13:43: " + getCheckMessage(WS_NOT_PRECEDED, "}"),
|
||||
};
|
||||
verify(checkConfig, getNonCompilablePath("InputAllowEmptyLambdaExpressions.java"),
|
||||
expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllowEmptyLambdaExpressionsWithAllowEmptyLambdaParameter() throws Exception {
|
||||
checkConfig.addAttribute("allowEmptyLambdas", "true");
|
||||
final String[] expected = {
|
||||
"12:29: " + getCheckMessage(WS_NOT_FOLLOWED, "{"),
|
||||
"12:30: " + getCheckMessage(WS_NOT_PRECEDED, "}"),
|
||||
"13:29: " + getCheckMessage(WS_NOT_FOLLOWED, "{"),
|
||||
"13:43: " + getCheckMessage(WS_NOT_PRECEDED, "}"),
|
||||
};
|
||||
verify(checkConfig, getNonCompilablePath("InputAllowEmptyLambdaExpressions.java"),
|
||||
expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
//Compilable with Java8
|
||||
package com.puppycrawl.tools.checkstyle.checks.whitespace;
|
||||
|
||||
import java.util.function.*;
|
||||
|
||||
public class InputAllowEmptyLambdaExpressions {
|
||||
Runnable noop = () -> {};
|
||||
Runnable noop2 = () -> {
|
||||
int x = 10;
|
||||
};
|
||||
BinaryOperator<Integer> sum = (x, y) -> x + y;
|
||||
Runnable noop3 = () -> {;};
|
||||
Runnable noop4 = () -> {new Integer();};
|
||||
}
|
||||
|
|
@ -1545,7 +1545,7 @@ foo(i,
|
|||
<subsection name="Description">
|
||||
<p>
|
||||
Checks that a token is surrounded by whitespace. Empty constructor,
|
||||
method, class, enum, interface, loop bodies (blocks) of the form
|
||||
method, class, enum, interface, loop bodies (blocks), lambdas of the form
|
||||
</p>
|
||||
|
||||
<source>public MyClass() {} // empty constructor
|
||||
|
|
@ -1557,13 +1557,15 @@ MyClass c = new MyClass() {}; // empty anonymous class
|
|||
while (i = 1) {} // empty while loop
|
||||
for (int i = 1; i > 1; i++) {} // empty for loop
|
||||
do {} while (i = 1); // empty do-while loop
|
||||
Runnable noop = () -> {}; // empty lambda
|
||||
public @interface Beta {} // empty annotation type
|
||||
</source>
|
||||
|
||||
<p>
|
||||
may optionally be exempted from the policy using the <code>
|
||||
allowEmptyMethods</code>, <code>allowEmptyConstructors
|
||||
</code>, <code>allowEmptyTypes</code> and <code>allowEmptyLoops</code> properties.
|
||||
</code>, <code>allowEmptyTypes</code>, <code>allowEmptyLoops</code> and
|
||||
<code>allowEmptyLambdas</code> properties.
|
||||
</p>
|
||||
</subsection>
|
||||
|
||||
|
|
@ -1599,6 +1601,12 @@ public @interface Beta {} // empty annotation type
|
|||
<td><a href="property_types.html#boolean">boolean</a></td>
|
||||
<td><code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>allowEmptyLambdas</td>
|
||||
<td>allow empty lambda bodies</td>
|
||||
<td><a href="property_types.html#boolean">boolean</a></td>
|
||||
<td><code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ignoreEnhancedForColon</td>
|
||||
<td>ignore whitespace around colon in for-each loops</td>
|
||||
|
|
|
|||
Loading…
Reference in New Issue