This commit is contained in:
Phil Race 2018-02-20 21:49:06 -08:00
commit 31dabd4d7f
17 changed files with 78 additions and 420 deletions

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,7 @@ DEFAULT_VERSION_FEATURE=11
DEFAULT_VERSION_INTERIM=0 DEFAULT_VERSION_INTERIM=0
DEFAULT_VERSION_UPDATE=0 DEFAULT_VERSION_UPDATE=0
DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_PATCH=0
DEFAULT_VERSION_DATE=2018-03-20 DEFAULT_VERSION_DATE=2018-09-18
DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_CLASSFILE_MINOR=0

View File

@ -1090,7 +1090,7 @@ var versionArgs = function(input, common) {
args = concat(args, args = concat(args,
// This needs to be changed when we start building release candidates // This needs to be changed when we start building release candidates
// with-version-pre must be set to ea for 'ea' and empty for fcs build // with-version-pre must be set to ea for 'ea' and empty for fcs build
"--with-version-pre=", "--with-version-pre=ea",
"--without-version-opt"); "--without-version-opt");
} else { } else {
args = concat(args, "--with-version-opt=" + common.build_id); args = concat(args, "--with-version-opt=" + common.build_id);

View File

@ -43,10 +43,11 @@ import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.Error; import com.sun.tools.javac.util.JCDiagnostic.Error;
import com.sun.tools.javac.util.JCDiagnostic.Warning; import com.sun.tools.javac.util.JCDiagnostic.Warning;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.JCDiagnostic.Fragment; import com.sun.tools.javac.util.JCDiagnostic.Fragment;
import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.parser.Tokens.TokenKind.*; import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT; import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
@ -289,31 +290,9 @@ public class JavacParser implements Parser {
/** Skip forward until a suitable stop token is found. /** Skip forward until a suitable stop token is found.
*/ */
protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement, boolean stopAtLambdaBody) { protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
while (true) { while (true) {
switch (token.kind) { switch (token.kind) {
case ARROW:
if (stopAtLambdaBody) {
//find end of lambda expression; this could be either a comma or an rparen (if in method context),
//or a semi colon (if in assignment context).
int depth = 0;
while (true) {
switch (token.kind) {
case EOF:
case LBRACE: depth++; break;
case RBRACE: depth--; break;
case COMMA:
case RPAREN:
case SEMI:
if (depth == 0) {
return;
}
break;
}
nextToken();
}
}
break;
case SEMI: case SEMI:
nextToken(); nextToken();
return; return;
@ -1097,8 +1076,7 @@ public class JavacParser implements Parser {
break; break;
case LPAREN: case LPAREN:
if (typeArgs == null && (mode & EXPR) != 0) { if (typeArgs == null && (mode & EXPR) != 0) {
LambdaClassfier lambdaClassifier = new LambdaClassfier(); ParensResult pres = analyzeParens();
ParensResult pres = analyzeParens(lambdaClassifier);
switch (pres) { switch (pres) {
case CAST: case CAST:
accept(LPAREN); accept(LPAREN);
@ -1117,15 +1095,9 @@ public class JavacParser implements Parser {
mode = EXPR; mode = EXPR;
JCExpression t1 = term3(); JCExpression t1 = term3();
return F.at(pos).TypeCast(t, t1); return F.at(pos).TypeCast(t, t1);
case BAD_LAMBDA:
Assert.checkNonNull(lambdaClassifier.diagFragment);
t = syntaxError(pos, List.nil(), Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment));
skip(false, false, false, false, true);
break;
case IMPLICIT_LAMBDA: case IMPLICIT_LAMBDA:
case EXPLICIT_LAMBDA: case EXPLICIT_LAMBDA:
case IMPLICIT_LAMBDA_ALL_VAR: t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos);
t = lambdaExpressionOrStatement(true, pres != ParensResult.IMPLICIT_LAMBDA, pos);
break; break;
default: //PARENS default: //PARENS
accept(LPAREN); accept(LPAREN);
@ -1537,17 +1509,15 @@ public class JavacParser implements Parser {
* matching '>' and see if the subsequent terminal is either '.' or '::'. * matching '>' and see if the subsequent terminal is either '.' or '::'.
*/ */
@SuppressWarnings("fallthrough") @SuppressWarnings("fallthrough")
ParensResult analyzeParens(LambdaClassfier lambdaClassifier) { ParensResult analyzeParens() {
int depth = 0; int depth = 0;
boolean type = false; boolean type = false;
outer: for (int lookahead = 0 ; ; lookahead++) { outer: for (int lookahead = 0 ; ; lookahead++) {
Token lookaheadToken = S.token(lookahead); TokenKind tk = S.token(lookahead).kind;
TokenKind tk = lookaheadToken.kind;
switch (tk) { switch (tk) {
case COMMA: case COMMA:
type = true; type = true;
break; case EXTENDS: case SUPER: case DOT: case AMP:
case FINAL: case EXTENDS: case SUPER: case DOT: case AMP:
//skip //skip
break; break;
case QUES: case QUES:
@ -1564,8 +1534,7 @@ public class JavacParser implements Parser {
return ParensResult.CAST; return ParensResult.CAST;
} else if (peekToken(lookahead, LAX_IDENTIFIER)) { } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
//Type, Identifier/'_'/'assert'/'enum' -> explicit lambda //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
lambdaClassifier.addExplicitParameter(); return ParensResult.EXPLICIT_LAMBDA;
lookahead++; //skip Identifier
} }
break; break;
case LPAREN: case LPAREN:
@ -1578,29 +1547,24 @@ public class JavacParser implements Parser {
} }
break; break;
case RPAREN: case RPAREN:
if (peekToken(lookahead, ARROW)) { // if we have seen something that looks like a type,
//this is a lambda // then it's a cast expression
return lambdaClassifier.result(); if (type) return ParensResult.CAST;
} else { // otherwise, disambiguate cast vs. parenthesized expression
// if we have seen something that looks like a type, // based on subsequent token.
// then it's a cast expression switch (S.token(lookahead + 1).kind) {
if (type) return ParensResult.CAST; /*case PLUSPLUS: case SUBSUB: */
// otherwise, disambiguate cast vs. parenthesized expression case BANG: case TILDE:
// based on subsequent token. case LPAREN: case THIS: case SUPER:
switch (S.token(lookahead + 1).kind) { case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
/*case PLUSPLUS: case SUBSUB: */ case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
case BANG: case TILDE: case TRUE: case FALSE: case NULL:
case LPAREN: case THIS: case SUPER: case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case BYTE: case SHORT: case CHAR: case INT:
case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
case TRUE: case FALSE: case NULL: return ParensResult.CAST;
case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE: default:
case BYTE: case SHORT: case CHAR: case INT: return ParensResult.PARENS;
case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
return ParensResult.CAST;
default:
return ParensResult.PARENS;
}
} }
case UNDERSCORE: case UNDERSCORE:
case ASSERT: case ASSERT:
@ -1608,23 +1572,17 @@ public class JavacParser implements Parser {
case IDENTIFIER: case IDENTIFIER:
if (peekToken(lookahead, LAX_IDENTIFIER)) { if (peekToken(lookahead, LAX_IDENTIFIER)) {
// Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && return ParensResult.EXPLICIT_LAMBDA;
lookaheadToken.name() == names.var) { } else if (peekToken(lookahead, RPAREN, ARROW)) {
lambdaClassifier.addImplicitVarParameter(); // Identifier, ')' '->' -> implicit lambda
} else { return ParensResult.IMPLICIT_LAMBDA;
lambdaClassifier.addExplicitParameter();
}
lookahead++; //skip Identifier
} else if ((!type && peekToken(lookahead, COMMA)) || peekToken(lookahead, RPAREN)) {
lambdaClassifier.addImplicitParameter();
} }
type = false; type = false;
break; break;
case FINAL:
case ELLIPSIS: case ELLIPSIS:
//those can only appear in explicit, non-var, lambdas //those can only appear in explicit lambdas
lambdaClassifier.addExplicitParameter(); return ParensResult.EXPLICIT_LAMBDA;
lookahead++; //skip Identifier
break;
case MONKEYS_AT: case MONKEYS_AT:
type = true; type = true;
lookahead += 1; //skip '@' lookahead += 1; //skip '@'
@ -1656,9 +1614,7 @@ public class JavacParser implements Parser {
case LBRACKET: case LBRACKET:
if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
// '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
lambdaClassifier.addExplicitParameter(); return ParensResult.EXPLICIT_LAMBDA;
lookahead += 2; //skip ']' Identifier
break;
} else if (peekToken(lookahead, RBRACKET, RPAREN) || } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
peekToken(lookahead, RBRACKET, AMP)) { peekToken(lookahead, RBRACKET, AMP)) {
// '[', ']', ')' -> cast // '[', ']', ')' -> cast
@ -1687,15 +1643,12 @@ public class JavacParser implements Parser {
// '>', '&' -> cast // '>', '&' -> cast
return ParensResult.CAST; return ParensResult.CAST;
} else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) || } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW)) { peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
peekToken(lookahead, ELLIPSIS)) {
// '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
// '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
lambdaClassifier.addExplicitParameter();
lookahead++; //skip Identifier
break;
} else if (peekToken(lookahead, ELLIPSIS)) {
// '>', '...' -> explicit lambda // '>', '...' -> explicit lambda
break; //this is handled in the outer switch return ParensResult.EXPLICIT_LAMBDA;
} }
//it looks a type, but could still be (i) a cast to generic type, //it looks a type, but could still be (i) a cast to generic type,
//(ii) an unbound method reference or (iii) an explicit lambda //(ii) an unbound method reference or (iii) an explicit lambda
@ -1713,61 +1666,6 @@ public class JavacParser implements Parser {
} }
} }
class LambdaClassfier {
ParensResult kind;
Fragment diagFragment;
void addExplicitParameter() {
reduce(ParensResult.EXPLICIT_LAMBDA);
}
void addImplicitVarParameter() {
reduce(ParensResult.IMPLICIT_LAMBDA_ALL_VAR);
}
void addImplicitParameter() {
reduce(ParensResult.IMPLICIT_LAMBDA);
}
private void reduce(ParensResult newKind) {
if (kind == null) {
kind = newKind;
} else if (kind != newKind && kind != ParensResult.BAD_LAMBDA) {
ParensResult currentKind = kind;
kind = ParensResult.BAD_LAMBDA;
switch (currentKind) {
case EXPLICIT_LAMBDA:
if (newKind == ParensResult.IMPLICIT_LAMBDA) {
diagFragment = Fragments.ImplicitAndExplicitNotAllowed;
} else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) {
diagFragment = Fragments.VarAndExplicitNotAllowed;
}
break;
case IMPLICIT_LAMBDA:
if (newKind == ParensResult.EXPLICIT_LAMBDA) {
diagFragment = Fragments.ImplicitAndExplicitNotAllowed;
} else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) {
diagFragment = Fragments.VarAndImplicitNotAllowed;
}
break;
case IMPLICIT_LAMBDA_ALL_VAR:
if (newKind == ParensResult.EXPLICIT_LAMBDA) {
diagFragment = Fragments.VarAndExplicitNotAllowed;
} else if (newKind == ParensResult.IMPLICIT_LAMBDA) {
diagFragment = Fragments.VarAndImplicitNotAllowed;
}
break;
default:
throw new AssertionError("unexpected option for field kind");
}
}
}
ParensResult result() {
return kind;
}
}
/** Accepts all identifier-like tokens */ /** Accepts all identifier-like tokens */
protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
@ -1775,15 +1673,7 @@ public class JavacParser implements Parser {
CAST, CAST,
EXPLICIT_LAMBDA, EXPLICIT_LAMBDA,
IMPLICIT_LAMBDA, IMPLICIT_LAMBDA,
IMPLICIT_LAMBDA_ALL_VAR, PARENS
BAD_LAMBDA,
PARENS;
}
enum BAD_LAMBDA_KIND {
EXPLICIT_AND_VAR,
IMPLICIT_AND_VAR,
EXPLICIT_AND_IMPLICIT,
} }
JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
@ -2006,9 +1896,6 @@ public class JavacParser implements Parser {
List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt(); List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
if (token.kind == LBRACKET) { if (token.kind == LBRACKET) {
if (t == null) {
log.error(token.pos, Errors.VarNotAllowedArray);
}
int pos = token.pos; int pos = token.pos;
nextToken(); nextToken();
t = bracketsOptCont(t, pos, nextLevelAnnotations); t = bracketsOptCont(t, pos, nextLevelAnnotations);
@ -2407,7 +2294,7 @@ public class JavacParser implements Parser {
if (token.pos == lastErrPos) if (token.pos == lastErrPos)
return stats.toList(); return stats.toList();
if (token.pos <= endPosTable.errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
skip(false, true, true, true, false); skip(false, true, true, true);
lastErrPos = token.pos; lastErrPos = token.pos;
} }
stats.addAll(stat); stats.addAll(stat);
@ -3246,7 +3133,7 @@ public class JavacParser implements Parser {
while (token.kind != EOF) { while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(checkForImports, false, false, false, false); skip(checkForImports, false, false, false);
if (token.kind == EOF) if (token.kind == EOF)
break; break;
} }
@ -3383,7 +3270,7 @@ public class JavacParser implements Parser {
defs.append(toP(F.at(pos).Provides(serviceName, implNames))); defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
} else { } else {
log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.ExpectedStr("'" + names.with + "'")); log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.ExpectedStr("'" + names.with + "'"));
skip(false, false, false, false, false); skip(false, false, false, false);
} }
} else if (token.name() == names.uses) { } else if (token.name() == names.uses) {
nextToken(); nextToken();
@ -3588,7 +3475,7 @@ public class JavacParser implements Parser {
false)); false));
if (token.pos <= endPosTable.errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, true, false, false); skip(false, true, true, false);
} }
} }
} }
@ -3650,7 +3537,7 @@ public class JavacParser implements Parser {
accept(LBRACE); accept(LBRACE);
if (token.pos <= endPosTable.errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, false, false, false); skip(false, true, false, false);
if (token.kind == LBRACE) if (token.kind == LBRACE)
nextToken(); nextToken();
} }
@ -3659,7 +3546,7 @@ public class JavacParser implements Parser {
defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
if (token.pos <= endPosTable.errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, true, false, false); skip(false, true, true, false);
} }
} }
accept(RBRACE); accept(RBRACE);
@ -3826,7 +3713,7 @@ public class JavacParser implements Parser {
accept(SEMI); accept(SEMI);
if (token.pos <= endPosTable.errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, false, false, false); skip(false, true, false, false);
if (token.kind == LBRACE) { if (token.kind == LBRACE) {
body = block(); body = block();
} }
@ -4060,7 +3947,7 @@ public class JavacParser implements Parser {
// need to distinguish between vararg annos and array annos // need to distinguish between vararg annos and array annos
// look at typeAnnotationsPushedBack comment // look at typeAnnotationsPushedBack comment
this.permitTypeAnnotationsPushBack = true; this.permitTypeAnnotationsPushBack = true;
JCExpression type = parseType(lambdaParameter); JCExpression type = parseType();
this.permitTypeAnnotationsPushBack = false; this.permitTypeAnnotationsPushBack = false;
if (token.kind == ELLIPSIS) { if (token.kind == ELLIPSIS) {
@ -4077,10 +3964,6 @@ public class JavacParser implements Parser {
} }
typeAnnotationsPushedBack = List.nil(); typeAnnotationsPushedBack = List.nil();
} }
if (lambdaParameter && isRestrictedLocalVarTypeName(type)) {
//implicit lambda parameter type (with 'var')
type = null;
}
return variableDeclaratorId(mods, type, lambdaParameter); return variableDeclaratorId(mods, type, lambdaParameter);
} }

View File

@ -1229,20 +1229,6 @@ compiler.err.var.not.allowed.array=\
compiler.err.var.not.allowed.compound=\ compiler.err.var.not.allowed.compound=\
''var'' is not allowed in a compound declaration ''var'' is not allowed in a compound declaration
# 0: fragment
compiler.err.invalid.lambda.parameter.declaration=\
invalid lambda parameter declaration\n\
({0})
compiler.misc.implicit.and.explicit.not.allowed=\
cannot mix implicitly-typed and explicitly-typed parameters
compiler.misc.var.and.explicit.not.allowed=\
cannot mix ''var'' and explicitly-typed parameters
compiler.misc.var.and.implicit.not.allowed=\
cannot mix ''var'' and implicitly-typed parameters
compiler.misc.local.cant.infer.null=\ compiler.misc.local.cant.infer.null=\
variable initializer is ''null'' variable initializer is ''null''

View File

@ -104,7 +104,7 @@ class ReplParser extends JavacParser {
while (token.kind != EOF) { while (token.kind != EOF) {
if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) { if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(true, false, false, false, false); skip(true, false, false, false);
if (token.kind == EOF) { if (token.kind == EOF) {
break; break;
} }

View File

@ -1,30 +0,0 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.var.not.allowed.array
import java.util.function.*;
class BracketsNotAllowedImplicitLambda {
BiFunction<String[], String, String> f = (var s1[], var s2) -> s2;
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.invalid.lambda.parameter.declaration
// key: compiler.misc.implicit.and.explicit.not.allowed
import java.util.function.*;
class ExplicitImplicitLambda {
IntBinaryOperator f = (int x, y) -> x + y;
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.invalid.lambda.parameter.declaration
// key: compiler.misc.var.and.implicit.not.allowed
import java.util.function.*;
class VarAllOrNothing {
IntBinaryOperator f = (x, var y) -> x + y;
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.invalid.lambda.parameter.declaration
// key: compiler.misc.var.and.explicit.not.allowed
import java.util.function.*;
class VarExplicitLambda {
IntBinaryOperator f = (int x, var y) -> x + y;
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.invalid.lambda.parameter.declaration
// key: compiler.misc.var.and.explicit.not.allowed
class VarNotAllowedExplicitLambda {
F f = (String s, var v)->{};
}

View File

@ -1,4 +1,4 @@
T8131742.java:8:31: compiler.err.expected: ')' T8131742.java:8:38: compiler.err.expected3: ',', ')', '['
T8131742.java:8:39: compiler.err.this.as.identifier T8131742.java:8:39: compiler.err.this.as.identifier
T8131742.java:8:43: compiler.err.expected: token.identifier T8131742.java:8:43: compiler.err.expected: ';'
3 errors 3 errors

View File

@ -40,7 +40,6 @@
*/ */
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import combo.ComboInstance; import combo.ComboInstance;
import combo.ComboParameter; import combo.ComboParameter;
@ -106,44 +105,26 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
} }
} }
enum SourceKind {
SOURCE_9("9"),
SOURCE_10("10");
String sourceNumber;
SourceKind(String sourceNumber) {
this.sourceNumber = sourceNumber;
}
}
enum LambdaParameterKind implements ComboParameter { enum LambdaParameterKind implements ComboParameter {
IMPLICIT(""),
IMPLICIT_1("", ExplicitKind.IMPLICIT), EXPLIICT_SIMPLE("A"),
IMPLICIT_2("var", ExplicitKind.IMPLICIT_VAR), EXPLIICT_SIMPLE_ARR1("A[]"),
EXPLIICT_SIMPLE("A", ExplicitKind.EXPLICIT), EXPLIICT_SIMPLE_ARR2("A[][]"),
EXPLIICT_SIMPLE_ARR1("A[]", ExplicitKind.EXPLICIT), EXPLICIT_VARARGS("A..."),
EXPLIICT_SIMPLE_ARR2("A[][]", ExplicitKind.EXPLICIT), EXPLICIT_GENERIC1("A<X>"),
EXPLICIT_VARARGS("A...", ExplicitKind.EXPLICIT), EXPLICIT_GENERIC2("A<? extends X, ? super Y>"),
EXPLICIT_GENERIC1("A<X>", ExplicitKind.EXPLICIT), EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>..."),
EXPLICIT_GENERIC2("A<? extends X, ? super Y>", ExplicitKind.EXPLICIT), EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]"),
EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>...", ExplicitKind.EXPLICIT), EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]");
EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]", ExplicitKind.EXPLICIT),
EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]", ExplicitKind.EXPLICIT);
enum ExplicitKind {
IMPLICIT,
IMPLICIT_VAR,
EXPLICIT;
}
String parameterType; String parameterType;
ExplicitKind explicitKind;
LambdaParameterKind(String parameterType) {
LambdaParameterKind(String parameterType, ExplicitKind ekind) {
this.parameterType = parameterType; this.parameterType = parameterType;
this.explicitKind = ekind; }
boolean explicit() {
return this != IMPLICIT;
} }
boolean isVarargs() { boolean isVarargs() {
@ -155,23 +136,12 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
public String expand(String optParameter) { public String expand(String optParameter) {
return parameterType; return parameterType;
} }
ExplicitKind explicitKind(SourceKind sk) {
switch (explicitKind) {
case IMPLICIT_VAR:
return (sk == SourceKind.SOURCE_9) ?
ExplicitKind.EXPLICIT : ExplicitKind.IMPLICIT_VAR;
default:
return explicitKind;
}
}
} }
enum ModifierKind implements ComboParameter { enum ModifierKind implements ComboParameter {
NONE(""), NONE(""),
FINAL("final"), FINAL("final"),
PUBLIC("public"), PUBLIC("public");
ANNO("@A");
String modifier; String modifier;
@ -182,8 +152,7 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
boolean compatibleWith(LambdaParameterKind pk) { boolean compatibleWith(LambdaParameterKind pk) {
switch (this) { switch (this) {
case PUBLIC: return false; case PUBLIC: return false;
case ANNO: case FINAL: return pk != LambdaParameterKind.IMPLICIT;
case FINAL: return pk != LambdaParameterKind.IMPLICIT_1;
case NONE: return true; case NONE: return true;
default: throw new AssertionError("Invalid modifier kind " + this); default: throw new AssertionError("Invalid modifier kind " + this);
} }
@ -239,7 +208,6 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
new ComboTestHelper<LambdaParserTest>() new ComboTestHelper<LambdaParserTest>()
.withFilter(LambdaParserTest::redundantTestFilter) .withFilter(LambdaParserTest::redundantTestFilter)
.withFilter(LambdaParserTest::badImplicitFilter) .withFilter(LambdaParserTest::badImplicitFilter)
.withDimension("SOURCE", (x, sk) -> x.sk = sk, SourceKind.values())
.withDimension("LAMBDA", (x, lk) -> x.lk = lk, LambdaKind.values()) .withDimension("LAMBDA", (x, lk) -> x.lk = lk, LambdaKind.values())
.withDimension("NAME", (x, name) -> x.pn = name, LambdaParameterName.values()) .withDimension("NAME", (x, name) -> x.pn = name, LambdaParameterName.values())
.withArrayDimension("TYPE", (x, type, idx) -> x.pks[idx] = type, 2, LambdaParameterKind.values()) .withArrayDimension("TYPE", (x, type, idx) -> x.pks[idx] = type, 2, LambdaParameterKind.values())
@ -253,7 +221,6 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
ModifierKind[] mks = new ModifierKind[2]; ModifierKind[] mks = new ModifierKind[2];
LambdaKind lk; LambdaKind lk;
LambdaParameterName pn; LambdaParameterName pn;
SourceKind sk;
boolean badImplicitFilter() { boolean badImplicitFilter() {
return !(mks[0] != ModifierKind.NONE && lk.isShort()); return !(mks[0] != ModifierKind.NONE && lk.isShort());
@ -273,15 +240,13 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
return true; return true;
} }
String template = "@interface A { }\n" + String template = "class Test {\n" +
"class Test {\n" + " SAM s = #{EXPR};\n" +
" SAM s = #{EXPR};\n" + "}";
"}";
@Override @Override
public void doWork() throws IOException { public void doWork() throws IOException {
newCompilationTask() newCompilationTask()
.withOptions(Arrays.asList("-source", sk.sourceNumber))
.withSourceFromTemplate(template) .withSourceFromTemplate(template)
.parse(this::check); .parse(this::check);
} }
@ -291,7 +256,7 @@ public class LambdaParserTest extends ComboInstance<LambdaParserTest> {
(lk.arity() > 1 && !mks[1].compatibleWith(pks[1])); (lk.arity() > 1 && !mks[1].compatibleWith(pks[1]));
if (lk.arity() == 2 && if (lk.arity() == 2 &&
(pks[0].explicitKind(sk) != pks[1].explicitKind(sk) || (pks[0].explicit() != pks[1].explicit() ||
pks[0].isVarargs())) { pks[0].isVarargs())) {
errorExpected = true; errorExpected = true;
} }

View File

@ -60,7 +60,7 @@ class ParserTest<var extends AutoCloseable> {
List<? extends var> l2; //error List<? extends var> l2; //error
List<? super var> l3; //error List<? super var> l3; //error
try { try {
Function<var, String> f = (var x2) -> ""; //ok Function<var, String> f = (var x2) -> ""; //error
} catch (var ex) { } //error } catch (var ex) { } //error
} }

View File

@ -18,7 +18,8 @@ ParserTest.java:59:14: compiler.err.var.not.allowed.here
ParserTest.java:60:24: compiler.err.var.not.allowed.here ParserTest.java:60:24: compiler.err.var.not.allowed.here
ParserTest.java:61:22: compiler.err.var.not.allowed.here ParserTest.java:61:22: compiler.err.var.not.allowed.here
ParserTest.java:63:22: compiler.err.var.not.allowed.here ParserTest.java:63:22: compiler.err.var.not.allowed.here
ParserTest.java:63:40: compiler.err.var.not.allowed.here
ParserTest.java:64:18: compiler.err.var.not.allowed.here ParserTest.java:64:18: compiler.err.var.not.allowed.here
ParserTest.java:68:35: compiler.err.var.not.allowed.here ParserTest.java:68:35: compiler.err.var.not.allowed.here
ParserTest.java:69:22: compiler.err.var.not.allowed.here ParserTest.java:69:22: compiler.err.var.not.allowed.here
23 errors 24 errors

View File

@ -104,7 +104,7 @@ class TrialParser extends JavacParser {
while (token.kind != EOF) { while (token.kind != EOF) {
if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) { if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(true, false, false, false, false); skip(true, false, false, false);
if (token.kind == EOF) { if (token.kind == EOF) {
break; break;
} }

View File

@ -1,17 +0,0 @@
/*
* @test /nodynamiccopyright/
* @bug 8194892
* @summary add compiler support for local-variable syntax for lambda parameters
* @compile/fail/ref=VarInImplicitLambdaNegTest01.out -XDrawDiagnostics VarInImplicitLambdaNegTest01.java
*/
import java.util.function.*;
class VarInImplicitLambdaNegTest01 {
IntBinaryOperator f1 = (x, var y) -> x + y;
IntBinaryOperator f2 = (var x, y) -> x + y;
IntBinaryOperator f3 = (int x, var y) -> x + y;
IntBinaryOperator f4 = (int x, y) -> x + y;
BiFunction<String[], String, String> f5 = (var s1[], var s2) -> s2;
}

View File

@ -1,6 +0,0 @@
VarInImplicitLambdaNegTest01.java:11:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
VarInImplicitLambdaNegTest01.java:12:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
VarInImplicitLambdaNegTest01.java:13:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.explicit.not.allowed)
VarInImplicitLambdaNegTest01.java:14:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
VarInImplicitLambdaNegTest01.java:16:54: compiler.err.var.not.allowed.array
5 errors