Issue 10. Lambda support has been added.

This commit is contained in:
Ilja Dubinin 2014-06-14 03:32:08 +04:00 committed by Ilja Dubinin
parent a70800ea2f
commit 6a9bc9181c
22 changed files with 643 additions and 10 deletions

View File

@ -3430,6 +3430,11 @@ public final class TokenTypes
*/
public static final int GENERIC_END = GeneratedJavaTokenTypes.GENERIC_END;
/**
* "->" lambda specifying symbol.
*/
public static final int LAMBDA = GeneratedJavaTokenTypes.LAMBDA;
////////////////////////////////////////////////////////////////////////
// The interesting code goes here
////////////////////////////////////////////////////////////////////////

View File

@ -95,6 +95,9 @@ tokens {
//Tokens for Java 1.7 language enhancements
RESOURCE_SPECIFICATION; RESOURCES; RESOURCE;
//TOkens for 1.8
LAMBDA;
}
{
@ -784,7 +787,7 @@ implementsClause
tc,
s2,
s5);}
| v:variableDefinitions[#mods,#t] s6:SEMI
| v:variableDefinitions[#mods,#t] (s6:SEMI)?
{
#field = #v;
#v.addChild(#s6);
@ -945,7 +948,7 @@ parameterModifier
// A formal parameter.
parameterDeclaration!
: pm:parameterModifier t:typeSpec[false] id:IDENT
: pm:parameterModifier (t:typeSpec[false])? id:IDENT
pd:declaratorBrackets[#t]
{#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"],
pm, #([TYPE,"TYPE"],pd), id);}
@ -1000,7 +1003,7 @@ traditionalStatement
// An expression statement. This could be a method call,
// assignment statement, or any other expression evaluated for
// side-effects.
| expression SEMI
| {LA(2) != COLON}? expression (SEMI)?
// class definition
| m:modifiers! classDefinition[#m]
@ -1222,7 +1225,8 @@ finallyHandler
// the mother of all expressions
expression
: assignmentExpression
: (lambdaExpression) => lambdaExpression
| {LA(1)!=RPAREN}? assignmentExpression
{#expression = #(#[EXPR,"EXPR"],#expression);}
;
@ -1250,7 +1254,8 @@ assignmentExpression
| BXOR_ASSIGN^
| BOR_ASSIGN^
)
assignmentExpression
((lambdaExpression)=>lambdaExpression
| assignmentExpression)
)?
;
@ -1258,7 +1263,11 @@ assignmentExpression
// conditional test (level 12)
conditionalExpression
: logicalOrExpression
( QUESTION^ assignmentExpression COLON conditionalExpression )?
( QUESTION^
((lambdaExpression)=>lambdaExpression
| assignmentExpression)
COLON ((lambdaExpression)=>lambdaExpression
| conditionalExpression) )?
;
@ -1300,7 +1309,7 @@ equalityExpression
// boolean relational expressions (level 5)
relationalExpression
: shiftExpression
: shiftExpression ( "instanceof"^ typeSpec[true])?
( ( ( LT^
| GT^
| LE^
@ -1308,7 +1317,7 @@ relationalExpression
)
shiftExpression
)*
| "instanceof"^ typeSpec[true]
)
;
@ -1361,6 +1370,10 @@ unaryExpressionNotPlusMinus
lp:LPAREN^ {#lp.setType(TYPECAST);} typeCastParameters RPAREN
unaryExpressionNotPlusMinus
| (LPAREN typeCastParameters RPAREN lambdaExpression) =>
lpl:LPAREN^ {#lpl.setType(TYPECAST);} typeCastParameters RPAREN
lambdaExpression
| postfixExpression
)
;
@ -1436,7 +1449,7 @@ primaryExpression
| "this"
| "null"
| newExpression
| LPAREN assignmentExpression RPAREN
| LPAREN ((lambdaExpression)=>lambdaExpression | assignmentExpression) RPAREN
| "super"
// look for int.class and int[].class and int[]
| builtInType
@ -1511,7 +1524,7 @@ newExpression
;
argList
: ( expressionList
: ( {LA(1)!=RPAREN}? expressionList
| /*nothing*/
{#argList = #[ELIST,"ELIST"];}
)
@ -1543,6 +1556,24 @@ constant
| STRING_LITERAL
;
lambdaExpression
: lambdaParameters LAMBDA^ lambdaBody
;
lambdaParameters
: IDENT
| LPAREN (parameterDeclarationList)? RPAREN
| LPAREN inferredParameterList RPAREN
;
lambdaBody
: expression
| statement
;
inferredParameterList
: IDENT (COMMA IDENT)*
;
//----------------------------------------------------------------------------
// The Java scanner
@ -1635,6 +1666,7 @@ SL : "<<" ;
SL_ASSIGN : "<<=" ;
LE : "<=" ;
LT : '<' ;
LAMBDA : "->" ;
BXOR : '^' ;
BXOR_ASSIGN : "^=" ;
BOR : '|' ;

View File

@ -0,0 +1,258 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2014 Oliver Burn
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.grammars.java8;
import org.junit.Test;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.checks.naming.MemberNameCheck;
public class LambdaTest extends BaseCheckTestSupport
{
@Test
public void testLambdaInVariableInitialization()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest1.java"),
expected);
}
@Test
public void testWithoutArgsOneLineLambdaBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest2.java"),
expected);
}
@Test
public void testWithoutArgsFullLambdaBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest3.java"),
expected);
}
@Test
public void testWithOneArgWithOneLineBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest4.java"),
expected);
}
@Test
public void testWithOneArgWithFullBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest5.java"),
expected);
}
@Test
public void testWithOneArgWIthoutTypeOneLineBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest6.java"),
expected);
}
@Test
public void testWithOneArgWIthoutTypeFullBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest7.java"),
expected);
}
@Test
public void testWithFewArgsWithoutTypeOneLineBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest8.java"),
expected);
}
@Test
public void testWithFewArgsWithoutTypeFullBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest9.java"),
expected);
}
@Test
public void testWithOneArgWIthoutParenthesesWithoutTypeOneLineBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest10.java"),
expected);
}
@Test
public void testWithOneArgWIthoutParenthesesWithoutTypeFullBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest11.java"),
expected);
}
@Test
public void testWithFewArgWIthTypeOneLine()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest12.java"),
expected);
}
@Test
public void testWithFewArgWithTypeFullBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest13.java"),
expected);
}
@Test
public void testWIthMultilineBody()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest14.java"),
expected);
}
@Test
public void testCasesFromSpec()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest15.java"),
expected);
}
@Test
public void testWithTypecast()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest16.java"),
expected);
}
@Test
public void testInAssignment()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest17.java"),
expected);
}
@Test
public void testInParentheses()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest18.java"),
expected);
}
@Test
public void testInTernary()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(MemberNameCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("grammars/java8/InputLambdaTest19.java"),
expected);
}
}

View File

@ -0,0 +1,12 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest1 {
static Runnable r1 = ()->System.out.println("Hello world one!");
static Runnable r2 = () -> System.out.println("Hello world two!");
public static void main(String[] args) {
r1.run();
r2.run();
}
}

View File

@ -0,0 +1,20 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest10 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth("fef");
}
public static void main(String[] args) {
testVoidLambda(s1 -> System.out.println(s1));
}
private interface TestOfVoidLambdas {
public void doSmth(String first);
}
}

View File

@ -0,0 +1,20 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest11 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth("fef");
}
public static void main(String[] args) {
testVoidLambda(s1 -> {System.out.println(s1);});
}
private interface TestOfVoidLambdas {
public void doSmth(String first);
}
}

View File

@ -0,0 +1,20 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest12 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth("fef", 5);
}
public static void main(String[] args) {
testVoidLambda((String s1, Integer i2) -> System.out.println(s1));
}
private interface TestOfVoidLambdas {
public void doSmth(String first, Integer second);
}
}

View File

@ -0,0 +1,22 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest12 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth("fef", 5);
}
public static void main(String[] args) {
testVoidLambda((String s1, Integer i2) -> {
System.out.println(s1);
});
}
private interface TestOfVoidLambdas {
public void doSmth(String first, Integer second);
}
}

View File

@ -0,0 +1,18 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
import java.util.Arrays;
import java.util.List;
public class InputLambdaTest14 {
public static void main(String args[]) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(first -> {
System.out.println("first");
System.out.println("second");
System.out.println("third");
});
}
}

View File

@ -0,0 +1,42 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
import java.util.Arrays;
import java.util.List;
public class InputLambdaTest15 {
public static void main(String args[]) {
() -> {}; // No parameters; result is void
() -> 42; // No parameters, expression body
() -> null; // No parameters, expression body
() -> { return 42; } // No parameters, block body with return
() -> { System.gc(); } // No parameters, void block body
() -> { // Complex block body with returns
if (true) return 12;
else {
int result = 15;
for (int i = 1; i < 10; i++)
{
result *= i;
}
return result;
};
}
(int x) -> x+1; // Single declared-type parameter
(int x) -> { return x+1; } // Single declared-type parameter
(x) -> x+1; // Single inferred-type parameter
x -> x+1; // Parentheses optional for
// single inferred-type parameter
(String s) -> s.length(); // Single declared-type parameter
(Thread t) -> { t.start(); } // Single declared-type parameter
s -> s.length(); // Single inferred-type parameter
t -> { t.start(); } // Single inferred-type parameter
(int x, int y) -> x+y; // Multiple declared-type parameters
(x, y) -> x+y; // Multiple inferred-type parameters
}
}

View File

@ -0,0 +1,21 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
import java.util.Arrays;
import java.util.List;
public class InputLambdaTest16 {
static final Comparator<ChronoLocalDateTime<? extends ChronoLocalDate>> DATE_TIME_ORDER =
(Comparator<ChronoLocalDateTime<? extends ChronoLocalDate>>) (dateTime1, dateTime2) -> {
int cmp = Long.compare(dateTime1.toLocalDate().toEpochDay(), dateTime2.toLocalDate().toEpochDay());
if (cmp == 0) {
cmp = Long.compare(dateTime1.toLocalTime().toNanoOfDay(), dateTime2.toLocalTime().toNanoOfDay());
}
return cmp;
};
public static void main(String args[]) {
}
}

View File

@ -0,0 +1,9 @@
public class InputLambdaTest17{
void initPartialTraversalState() {
SpinedBuffer<P_OUT> b = new SpinedBuffer<>();
buffer = b;
pusher = () -> spliterator.tryAdvance(bufferSink);
}
}

View File

@ -0,0 +1,13 @@
public class InputLambdaTest18 {
<T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.
getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).
collect(Collectors.toMap(Annotation.annotationType(),
Function.identity(),
((first,second) -> first),
LinkedHashMap.neww())),
annotationClass);
}
}

View File

@ -0,0 +1,8 @@
public class InputLambdaTest19 {
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? true
: object -> targetRef.equals(object);
}
}

View File

@ -0,0 +1,24 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
import java.util.Arrays;
import java.util.List;
import TestLabmda.TestOfVoidLambdas;
public class InputLabdaTest2 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth();
}
public static void main(String[] args) {
testVoidLambda(() -> System.out.println("Method in interface called"));
}
private interface TestOfVoidLambdas {
public void doSmth();
}
}

View File

@ -0,0 +1,26 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
import java.util.Arrays;
import java.util.List;
import TestLabmda.TestOfVoidLambdas;
public class InputLabdaTest3 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth();
}
public static void main(String[] args) {
testVoidLambda(() -> {
System.out.println("Method in interface called");
});
}
private interface TestOfVoidLambdas {
public void doSmth();
}
}

View File

@ -0,0 +1,10 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest4 {
public void doSomething() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.forEach((Integer value) -> System.out.println(value));
}
}

View File

@ -0,0 +1,10 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest5 {
public void doSomething() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.forEach((Integer value) -> {System.out.println(value);});
}
}

View File

@ -0,0 +1,10 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest6 {
public void doSomething() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.forEach((value) -> System.out.println(value));
}
}

View File

@ -0,0 +1,15 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
import java.util.Arrays;
import java.util.List;
public class InputLabdaTest7 {
public void doSomething() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.forEach((value) -> {
System.out.println(value);
});
}
}

View File

@ -0,0 +1,19 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest8 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth("fef", 2);
}
public static void main(String[] args) {
testVoidLambda((s1, s2) -> System.out.println(s1 + s2));
}
private interface TestOfVoidLambdas {
public void doSmth(String first, Integer second);
}
}

View File

@ -0,0 +1,19 @@
package com.puppycrawl.tools.checkstyle.grammars.java8;
public class InputLabdaTest9 {
public static void testVoidLambda(TestOfVoidLambdas test) {
System.out.println("Method called");
test.doSmth("fef", 2);
}
public static void main(String[] args) {
testVoidLambda((s1, s2) -> {System.out.println(s1 + s2);});
}
private interface TestOfVoidLambdas {
public void doSmth(String first, Integer second);
}
}