langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Nov 19 13:46:04 2014 +0100
@@ -145,6 +145,8 @@
this.names = fac.names;
this.source = fac.source;
this.allowTWR = source.allowTryWithResources();
+ this.allowEffectivelyFinalVariablesInTWR =
+ source.allowEffectivelyFinalVariablesInTryWithResources();
this.allowDiamond = source.allowDiamond();
this.allowMulticatch = source.allowMulticatch();
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
@@ -184,6 +186,10 @@
*/
boolean allowTWR;
+ /** Switch: should we allow (effectively) final variables as resources in try-with-resources?
+ */
+ boolean allowEffectivelyFinalVariablesInTWR;
+
/** Switch: should we fold strings?
*/
boolean allowStringFolding;
@@ -3003,14 +3009,28 @@
return defs.toList();
}
- /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
+ /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
+ * | Expression
*/
protected JCTree resource() {
- JCModifiers optFinal = optFinal(Flags.FINAL);
- JCExpression type = parseType();
- int pos = token.pos;
- Name ident = ident();
- return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
+ int startPos = token.pos;
+ if (token.kind == FINAL || token.kind == MONKEYS_AT) {
+ JCModifiers mods = optFinal(Flags.FINAL);
+ JCExpression t = parseType();
+ return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
+ }
+ JCExpression t = term(EXPR | TYPE);
+ if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
+ JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
+ return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
+ } else {
+ checkVariableInTryWithResources(startPos);
+ if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
+ log.error(t.pos(), "try.with.resources.expr.needs.var");
+ }
+
+ return t;
+ }
}
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
@@ -3933,6 +3953,12 @@
allowTWR = true;
}
}
+ void checkVariableInTryWithResources(int startPos) {
+ if (!allowEffectivelyFinalVariablesInTWR) {
+ error(startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
+ allowEffectivelyFinalVariablesInTWR = true;
+ }
+ }
void checkLambda() {
if (!allowLambda) {
log.error(token.pos, "lambda.not.supported.in.source", source.name);