mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8223305: Compiler support for Switch Expressions
Reviewed-by: mcimadamore, vromero
This commit is contained in:
parent
c569ad302a
commit
b34b2d993c
88 changed files with 2033 additions and 829 deletions
|
@ -257,8 +257,8 @@ public enum SourceVersion {
|
||||||
* followed only by characters for which {@link
|
* followed only by characters for which {@link
|
||||||
* Character#isJavaIdentifierPart(int)} returns {@code true}.
|
* Character#isJavaIdentifierPart(int)} returns {@code true}.
|
||||||
* This pattern matches regular identifiers, keywords, restricted
|
* This pattern matches regular identifiers, keywords, restricted
|
||||||
* keywords, and the literals {@code "true"}, {@code "false"},
|
* keywords, restricted identifiers and the literals {@code "true"},
|
||||||
* {@code "null"}, and {@code "var"}.
|
* {@code "false"}, {@code "null"}.
|
||||||
*
|
*
|
||||||
* The method returns {@code false} for all other strings.
|
* The method returns {@code false} for all other strings.
|
||||||
*
|
*
|
||||||
|
@ -295,7 +295,7 @@ public enum SourceVersion {
|
||||||
* for keywords, boolean literals, and the null literal.
|
* for keywords, boolean literals, and the null literal.
|
||||||
*
|
*
|
||||||
* This method returns {@code true} for <i>restricted
|
* This method returns {@code true} for <i>restricted
|
||||||
* keywords</i> and {@code "var"}.
|
* keywords</i> and <i>restricted identifiers</i>
|
||||||
*
|
*
|
||||||
* @param name the string to check
|
* @param name the string to check
|
||||||
* @return {@code true} if this string is a
|
* @return {@code true} if this string is a
|
||||||
|
@ -314,7 +314,7 @@ public enum SourceVersion {
|
||||||
* for keywords, boolean literals, and the null literal.
|
* for keywords, boolean literals, and the null literal.
|
||||||
*
|
*
|
||||||
* This method returns {@code true} for <i>restricted
|
* This method returns {@code true} for <i>restricted
|
||||||
* keywords</i> and {@code "var"}.
|
* keywords</i> and <i>restricted identifiers</i>
|
||||||
*
|
*
|
||||||
* @param name the string to check
|
* @param name the string to check
|
||||||
* @param version the version to use
|
* @param version the version to use
|
||||||
|
@ -338,7 +338,7 @@ public enum SourceVersion {
|
||||||
* Returns whether or not {@code s} is a keyword, boolean literal,
|
* Returns whether or not {@code s} is a keyword, boolean literal,
|
||||||
* or null literal in the latest source version.
|
* or null literal in the latest source version.
|
||||||
* This method returns {@code false} for <i>restricted
|
* This method returns {@code false} for <i>restricted
|
||||||
* keywords</i> and {@code "var"}.
|
* keywords</i> and <i>restricted identifiers</i>.
|
||||||
*
|
*
|
||||||
* @param s the string to check
|
* @param s the string to check
|
||||||
* @return {@code true} if {@code s} is a keyword, or boolean
|
* @return {@code true} if {@code s} is a keyword, or boolean
|
||||||
|
@ -355,7 +355,7 @@ public enum SourceVersion {
|
||||||
* Returns whether or not {@code s} is a keyword, boolean literal,
|
* Returns whether or not {@code s} is a keyword, boolean literal,
|
||||||
* or null literal in the given source version.
|
* or null literal in the given source version.
|
||||||
* This method returns {@code false} for <i>restricted
|
* This method returns {@code false} for <i>restricted
|
||||||
* keywords</i> and {@code "var"}.
|
* keywords</i> and <i>restricted identifiers</i>.
|
||||||
*
|
*
|
||||||
* @param s the string to check
|
* @param s the string to check
|
||||||
* @param version the version to use
|
* @param version the version to use
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2019, 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
|
||||||
|
@ -35,8 +35,6 @@ import javax.lang.model.element.Name;
|
||||||
* break;
|
* break;
|
||||||
*
|
*
|
||||||
* break <em>label</em> ;
|
* break <em>label</em> ;
|
||||||
*
|
|
||||||
* break <em>expression</em> ;
|
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @jls 14.15 The break Statement
|
* @jls 14.15 The break Statement
|
||||||
|
@ -52,17 +50,4 @@ public interface BreakTree extends StatementTree {
|
||||||
*/
|
*/
|
||||||
Name getLabel();
|
Name getLabel();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the expression for this {@code break} statement.
|
|
||||||
*
|
|
||||||
* @return the expression
|
|
||||||
* @since 12
|
|
||||||
*
|
|
||||||
* @deprecated This method is modeling value breaks, which are part of
|
|
||||||
* a preview feature and may be removed if the preview feature
|
|
||||||
* is removed.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval=true, since="12")
|
|
||||||
ExpressionTree getValue();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2019, 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
|
||||||
|
@ -656,7 +656,21 @@ public interface Tree {
|
||||||
* An implementation-reserved node. This is the not the node
|
* An implementation-reserved node. This is the not the node
|
||||||
* you are looking for.
|
* you are looking for.
|
||||||
*/
|
*/
|
||||||
OTHER(null);
|
OTHER(null),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for instances of {@link YieldTree}.
|
||||||
|
*
|
||||||
|
* @since 13
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
* This enum constant is modeling yield statement,
|
||||||
|
* which are part of a preview feature and may be removed
|
||||||
|
* if the preview feature is removed.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval=true, since="13")
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
YIELD(YieldTree.class);
|
||||||
|
|
||||||
|
|
||||||
Kind(Class<? extends Tree> intf) {
|
Kind(Class<? extends Tree> intf) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2019, 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
|
||||||
|
@ -555,4 +555,20 @@ public interface TreeVisitor<R,P> {
|
||||||
* @return a result value
|
* @return a result value
|
||||||
*/
|
*/
|
||||||
R visitOther(Tree node, P p);
|
R visitOther(Tree node, P p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a YieldTree node.
|
||||||
|
* @param node the node being visited
|
||||||
|
* @param p a parameter value
|
||||||
|
* @return a result value
|
||||||
|
* @since 13
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
* This method is modeling yield statement,
|
||||||
|
* which are part of a preview feature and may be removed
|
||||||
|
* if the preview feature is removed.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval=true, since="13")
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
R visitYield(YieldTree node, P p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sun.source.tree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tree node for a {@code yield} statement.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* <pre>
|
||||||
|
* yield <em>expression</em> ;
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @jls section TODO
|
||||||
|
*
|
||||||
|
* @since 13
|
||||||
|
*
|
||||||
|
* @deprecated This class is modeling yield from switch expressions,
|
||||||
|
* which are part of a preview feature and may be removed if
|
||||||
|
* the preview feature is removed.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval=true, since="13")
|
||||||
|
public interface YieldTree extends StatementTree {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the expression for this {@code yield} statement.
|
||||||
|
*
|
||||||
|
* @return the expression
|
||||||
|
*/
|
||||||
|
ExpressionTree getValue();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2019, 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
|
||||||
|
@ -782,4 +782,18 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
|
||||||
public R visitOther(Tree node, P p) {
|
public R visitOther(Tree node, P p) {
|
||||||
return defaultAction(node, p);
|
return defaultAction(node, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc} This implementation calls {@code defaultAction}.
|
||||||
|
*
|
||||||
|
* @param node {@inheritDoc}
|
||||||
|
* @param p {@inheritDoc}
|
||||||
|
* @return the result of {@code defaultAction}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Deprecated(forRemoval=true, since="13")
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
public R visitYield(YieldTree node, P p) {
|
||||||
|
return defaultAction(node, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2019, 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
|
||||||
|
@ -467,9 +467,8 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
||||||
* @return the result of scanning
|
* @return the result of scanning
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("removal")
|
|
||||||
public R visitBreak(BreakTree node, P p) {
|
public R visitBreak(BreakTree node, P p) {
|
||||||
return scan(node.getValue(), p);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -935,4 +934,23 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
||||||
public R visitErroneous(ErroneousTree node, P p) {
|
public R visitErroneous(ErroneousTree node, P p) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc} This implementation returns {@code null}.
|
||||||
|
*
|
||||||
|
* @param node {@inheritDoc}
|
||||||
|
* @param p {@inheritDoc}
|
||||||
|
* @return the result of scanning
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
* This method is modeling switch expressions,
|
||||||
|
* which are part of a preview feature and may be removed
|
||||||
|
* if the preview feature is removed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Deprecated(forRemoval=true, since="13")
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
public R visitYield(YieldTree node, P p) {
|
||||||
|
return scan(node.getValue(), p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class Kinds {
|
||||||
HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target
|
HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target
|
||||||
STATICERR(Category.RESOLUTION_TARGET), // overloaded? target
|
STATICERR(Category.RESOLUTION_TARGET), // overloaded? target
|
||||||
MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target
|
MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target
|
||||||
BAD_VAR(Category.RESOLUTION), // not overloaded non-target
|
BAD_RESTRICTED_TYPE(Category.RESOLUTION), // not overloaded non-target
|
||||||
ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target
|
ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target
|
||||||
WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target
|
WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target
|
||||||
WRONG_MTH(Category.RESOLUTION_TARGET, KindName.METHOD), // not overloaded target
|
WRONG_MTH(Category.RESOLUTION_TARGET, KindName.METHOD), // not overloaded target
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2019, 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
|
||||||
|
@ -43,7 +43,6 @@ import com.sun.tools.javac.comp.Infer.PartiallyInferredMethodType;
|
||||||
import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
|
import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
|
||||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||||
import com.sun.tools.javac.tree.JCTree;
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCBreak;
|
|
||||||
import com.sun.tools.javac.tree.JCTree.JCConditional;
|
import com.sun.tools.javac.tree.JCTree.JCConditional;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCLambda;
|
import com.sun.tools.javac.tree.JCTree.JCLambda;
|
||||||
|
@ -77,6 +76,7 @@ import static com.sun.tools.javac.code.TypeTag.DEFERRED;
|
||||||
import static com.sun.tools.javac.code.TypeTag.FORALL;
|
import static com.sun.tools.javac.code.TypeTag.FORALL;
|
||||||
import static com.sun.tools.javac.code.TypeTag.METHOD;
|
import static com.sun.tools.javac.code.TypeTag.METHOD;
|
||||||
import static com.sun.tools.javac.code.TypeTag.VOID;
|
import static com.sun.tools.javac.code.TypeTag.VOID;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCYield;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class performs attribution of method/constructor arguments when target-typing is enabled
|
* This class performs attribution of method/constructor arguments when target-typing is enabled
|
||||||
|
@ -468,7 +468,7 @@ public class ArgumentAttr extends JCTree.Visitor {
|
||||||
*/
|
*/
|
||||||
class SwitchExpressionType extends ArgumentType<JCSwitchExpression> {
|
class SwitchExpressionType extends ArgumentType<JCSwitchExpression> {
|
||||||
/** List of break expressions (lazily populated). */
|
/** List of break expressions (lazily populated). */
|
||||||
Optional<List<JCBreak>> breakExpressions = Optional.empty();
|
Optional<List<JCYield>> yieldExpressions = Optional.empty();
|
||||||
|
|
||||||
SwitchExpressionType(JCExpression tree, Env<AttrContext> env, JCSwitchExpression speculativeCond) {
|
SwitchExpressionType(JCExpression tree, Env<AttrContext> env, JCSwitchExpression speculativeCond) {
|
||||||
this(tree, env, speculativeCond, new HashMap<>());
|
this(tree, env, speculativeCond, new HashMap<>());
|
||||||
|
@ -487,7 +487,7 @@ public class ArgumentAttr extends JCTree.Visitor {
|
||||||
return attr.types.createErrorType(resultInfo.pt);
|
return attr.types.createErrorType(resultInfo.pt);
|
||||||
} else {
|
} else {
|
||||||
//poly
|
//poly
|
||||||
for (JCBreak brk : breakExpressions()) {
|
for (JCYield brk : yieldExpressions()) {
|
||||||
checkSpeculative(brk.value, brk.value.type, resultInfo);
|
checkSpeculative(brk.value, brk.value.type, resultInfo);
|
||||||
}
|
}
|
||||||
return localInfo.pt;
|
return localInfo.pt;
|
||||||
|
@ -495,19 +495,20 @@ public class ArgumentAttr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compute return expressions (if needed). */
|
/** Compute return expressions (if needed). */
|
||||||
List<JCBreak> breakExpressions() {
|
List<JCYield> yieldExpressions() {
|
||||||
return breakExpressions.orElseGet(() -> {
|
return yieldExpressions.orElseGet(() -> {
|
||||||
final List<JCBreak> res;
|
final List<JCYield> res;
|
||||||
ListBuffer<JCBreak> buf = new ListBuffer<>();
|
ListBuffer<JCYield> buf = new ListBuffer<>();
|
||||||
new SwitchExpressionScanner() {
|
new SwitchExpressionScanner() {
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitYield(JCYield tree) {
|
||||||
if (tree.target == speculativeTree)
|
if (tree.target == speculativeTree)
|
||||||
buf.add(tree);
|
buf.add(tree);
|
||||||
|
super.visitYield(tree);
|
||||||
}
|
}
|
||||||
}.scan(speculativeTree.cases);
|
}.scan(speculativeTree.cases);
|
||||||
res = buf.toList();
|
res = buf.toList();
|
||||||
breakExpressions = Optional.of(res);
|
yieldExpressions = Optional.of(res);
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ import static com.sun.tools.javac.code.TypeTag.WILDCARD;
|
||||||
import com.sun.tools.javac.comp.Analyzer.AnalyzerMode;
|
import com.sun.tools.javac.comp.Analyzer.AnalyzerMode;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
||||||
|
import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
|
||||||
|
import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
|
||||||
|
|
||||||
/** This is the main context-dependent analysis phase in GJC. It
|
/** This is the main context-dependent analysis phase in GJC. It
|
||||||
* encompasses name resolution, type checking and constant folding as
|
* encompasses name resolution, type checking and constant folding as
|
||||||
|
@ -358,7 +360,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
Name name = (Name)node.getIdentifier();
|
Name name = (Name)node.getIdentifier();
|
||||||
if (site.kind == PCK) {
|
if (site.kind == PCK) {
|
||||||
env.toplevel.packge = (PackageSymbol)site;
|
env.toplevel.packge = (PackageSymbol)site;
|
||||||
return rs.findIdentInPackage(env, (TypeSymbol)site, name,
|
return rs.findIdentInPackage(null, env, (TypeSymbol)site, name,
|
||||||
KindSelector.TYP_PCK);
|
KindSelector.TYP_PCK);
|
||||||
} else {
|
} else {
|
||||||
env.enclClass.sym = (ClassSymbol)site;
|
env.enclClass.sym = (ClassSymbol)site;
|
||||||
|
@ -368,7 +370,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
|
|
||||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||||
public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) {
|
public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) {
|
||||||
return rs.findIdent(env, (Name)node.getName(), KindSelector.TYP_PCK);
|
return rs.findIdent(null, env, (Name)node.getName(), KindSelector.TYP_PCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,16 +1427,16 @@ public class Attr extends JCTree.Visitor {
|
||||||
ListBuffer<Type> caseTypes = new ListBuffer<>();
|
ListBuffer<Type> caseTypes = new ListBuffer<>();
|
||||||
|
|
||||||
handleSwitch(tree, tree.selector, tree.cases, (c, caseEnv) -> {
|
handleSwitch(tree, tree.selector, tree.cases, (c, caseEnv) -> {
|
||||||
caseEnv.info.breakResult = condInfo;
|
caseEnv.info.yieldResult = condInfo;
|
||||||
attribStats(c.stats, caseEnv);
|
attribStats(c.stats, caseEnv);
|
||||||
new TreeScanner() {
|
new TreeScanner() {
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak brk) {
|
public void visitYield(JCYield brk) {
|
||||||
if (brk.target == tree) {
|
if (brk.target == tree) {
|
||||||
caseTypePositions.append(brk.value != null ? brk.value.pos() : brk.pos());
|
caseTypePositions.append(brk.value != null ? brk.value.pos() : brk.pos());
|
||||||
caseTypes.append(brk.value != null ? brk.value.type : syms.errType);
|
caseTypes.append(brk.value != null ? brk.value.type : syms.errType);
|
||||||
}
|
}
|
||||||
super.visitBreak(brk);
|
super.visitYield(brk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void visitClassDef(JCClassDecl tree) {}
|
@Override public void visitClassDef(JCClassDecl tree) {}
|
||||||
|
@ -1864,67 +1866,19 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (env.info.breakResult != null) {
|
tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
|
||||||
if (tree.value == null) {
|
result = null;
|
||||||
tree.target = findJumpTarget(tree.pos(), tree.getTag(), null, env);
|
}
|
||||||
if (tree.target.hasTag(SWITCH_EXPRESSION)) {
|
|
||||||
log.error(tree.pos(), Errors.BreakMissingValue);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (env.info.breakResult.pt.hasTag(VOID)) {
|
|
||||||
//can happen?
|
|
||||||
env.info.breakResult.checkContext.report(tree.value.pos(),
|
|
||||||
diags.fragment(Fragments.UnexpectedRetVal));
|
|
||||||
}
|
|
||||||
boolean attribute = true;
|
|
||||||
if (tree.value.hasTag(IDENT)) {
|
|
||||||
//disambiguate break <LABEL> and break <ident-as-an-expression>:
|
|
||||||
Name label = ((JCIdent) tree.value).name;
|
|
||||||
Pair<JCTree, Error> jumpTarget = findJumpTargetNoError(tree.getTag(), label, env);
|
|
||||||
|
|
||||||
if (jumpTarget.fst != null) {
|
public void visitYield(JCYield tree) {
|
||||||
JCTree speculative = deferredAttr.attribSpeculative(tree.value, env, unknownExprInfo);
|
if (env.info.yieldResult != null) {
|
||||||
if (!speculative.type.hasTag(ERROR)) {
|
attribTree(tree.value, env, env.info.yieldResult);
|
||||||
log.error(tree.pos(), Errors.BreakAmbiguousTarget(label));
|
tree.target = findJumpTarget(tree.pos(), tree.getTag(), names.empty, env);
|
||||||
if (jumpTarget.snd == null) {
|
|
||||||
tree.target = jumpTarget.fst;
|
|
||||||
attribute = false;
|
|
||||||
} else {
|
|
||||||
//nothing
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (jumpTarget.snd != null) {
|
|
||||||
log.error(tree.pos(), jumpTarget.snd);
|
|
||||||
}
|
|
||||||
tree.target = jumpTarget.fst;
|
|
||||||
attribute = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (attribute) {
|
|
||||||
attribTree(tree.value, env, env.info.breakResult);
|
|
||||||
JCTree immediateTarget = findJumpTarget(tree.pos(), tree.getTag(), null, env);
|
|
||||||
if (immediateTarget.getTag() != SWITCH_EXPRESSION) {
|
|
||||||
log.error(tree.pos(), Errors.BreakExprNotImmediate(immediateTarget.getTag()));
|
|
||||||
Env<AttrContext> env1 = env;
|
|
||||||
while (env1 != null && env1.tree.getTag() != SWITCH_EXPRESSION) {
|
|
||||||
env1 = env1.next;
|
|
||||||
}
|
|
||||||
Assert.checkNonNull(env1);
|
|
||||||
tree.target = env1.tree;
|
|
||||||
} else {
|
|
||||||
tree.target = immediateTarget;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (tree.value == null || tree.value.hasTag(IDENT)) {
|
log.error(tree.pos(), tree.value.hasTag(PARENS)
|
||||||
Name label = tree.value != null ? ((JCIdent) tree.value).name : null;
|
? Errors.NoSwitchExpressionQualify
|
||||||
tree.target = findJumpTarget(tree.pos(), tree.getTag(), label, env);
|
: Errors.NoSwitchExpression);
|
||||||
} else {
|
attribTree(tree.value, env, unknownExprInfo);
|
||||||
log.error(tree.pos(), Errors.BreakComplexValueNoSwitchExpression);
|
|
||||||
attribTree(tree.value, env, unknownExprInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
|
@ -1934,8 +1888,8 @@ public class Attr extends JCTree.Visitor {
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
//where
|
//where
|
||||||
/** Return the target of a break or continue statement, if it exists,
|
/** Return the target of a break, continue or yield statement,
|
||||||
* report an error if not.
|
* if it exists, report an error if not.
|
||||||
* Note: The target of a labelled break or continue is the
|
* Note: The target of a labelled break or continue is the
|
||||||
* (non-labelled) statement tree referred to by the label,
|
* (non-labelled) statement tree referred to by the label,
|
||||||
* not the tree representing the labelled statement itself.
|
* not the tree representing the labelled statement itself.
|
||||||
|
@ -2009,12 +1963,10 @@ public class Attr extends JCTree.Visitor {
|
||||||
if (label == null && tag == BREAK) return Pair.of(env1.tree, null);
|
if (label == null && tag == BREAK) return Pair.of(env1.tree, null);
|
||||||
break;
|
break;
|
||||||
case SWITCH_EXPRESSION:
|
case SWITCH_EXPRESSION:
|
||||||
if (tag == BREAK) {
|
if (tag == YIELD) {
|
||||||
if (label == null) {
|
return Pair.of(env1.tree, null);
|
||||||
return Pair.of(env1.tree, null);
|
} else if (tag == BREAK) {
|
||||||
} else {
|
pendingError = Errors.BreakOutsideSwitchExpression;
|
||||||
pendingError = Errors.BreakOutsideSwitchExpression;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
pendingError = Errors.ContinueOutsideSwitchExpression;
|
pendingError = Errors.ContinueOutsideSwitchExpression;
|
||||||
}
|
}
|
||||||
|
@ -2029,6 +1981,8 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
if (label != null)
|
if (label != null)
|
||||||
return Pair.of(null, Errors.UndefLabel(label));
|
return Pair.of(null, Errors.UndefLabel(label));
|
||||||
|
else if (pendingError != null)
|
||||||
|
return Pair.of(null, pendingError);
|
||||||
else if (tag == CONTINUE)
|
else if (tag == CONTINUE)
|
||||||
return Pair.of(null, Errors.ContOutsideLoop);
|
return Pair.of(null, Errors.ContOutsideLoop);
|
||||||
else
|
else
|
||||||
|
@ -2040,7 +1994,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
// nested within than the enclosing class.
|
// nested within than the enclosing class.
|
||||||
if (env.info.returnResult == null) {
|
if (env.info.returnResult == null) {
|
||||||
log.error(tree.pos(), Errors.RetOutsideMeth);
|
log.error(tree.pos(), Errors.RetOutsideMeth);
|
||||||
} else if (env.info.breakResult != null) {
|
} else if (env.info.yieldResult != null) {
|
||||||
log.error(tree.pos(), Errors.ReturnOutsideSwitchExpression);
|
log.error(tree.pos(), Errors.ReturnOutsideSwitchExpression);
|
||||||
} else {
|
} else {
|
||||||
// Attribute return expression, if it exists, and check that
|
// Attribute return expression, if it exists, and check that
|
||||||
|
@ -3136,7 +3090,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
} else {
|
} else {
|
||||||
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
|
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
|
||||||
}
|
}
|
||||||
lambdaEnv.info.breakResult = null;
|
lambdaEnv.info.yieldResult = null;
|
||||||
return lambdaEnv;
|
return lambdaEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3916,7 +3870,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
switch (site.getTag()) {
|
switch (site.getTag()) {
|
||||||
case PACKAGE:
|
case PACKAGE:
|
||||||
return rs.accessBase(
|
return rs.accessBase(
|
||||||
rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
|
rs.findIdentInPackage(pos, env, site.tsym, name, resultInfo.pkind),
|
||||||
pos, location, site, name, true);
|
pos, location, site, name, true);
|
||||||
case ARRAY:
|
case ARRAY:
|
||||||
case CLASS:
|
case CLASS:
|
||||||
|
@ -3931,7 +3885,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
return syms.getClassField(site, types);
|
return syms.getClassField(site, types);
|
||||||
} else {
|
} else {
|
||||||
// We are seeing a plain identifier as selector.
|
// We are seeing a plain identifier as selector.
|
||||||
Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind);
|
Symbol sym = rs.findIdentInType(pos, env, site, name, resultInfo.pkind);
|
||||||
sym = rs.accessBase(sym, pos, location, site, name, true);
|
sym = rs.accessBase(sym, pos, location, site, name, true);
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -101,10 +101,10 @@ public class AttrContext {
|
||||||
*/
|
*/
|
||||||
Attr.ResultInfo returnResult = null;
|
Attr.ResultInfo returnResult = null;
|
||||||
|
|
||||||
/** ResultInfo to be used for attributing 'break' statement expressions
|
/** ResultInfo to be used for attributing 'yield' statement expressions
|
||||||
* (set by Attr.visitSwitchExpression)
|
* (set by Attr.visitSwitchExpression)
|
||||||
*/
|
*/
|
||||||
Attr.ResultInfo breakResult = null;
|
Attr.ResultInfo yieldResult = null;
|
||||||
|
|
||||||
/** Symbol corresponding to the site of a qualified default super call
|
/** Symbol corresponding to the site of a qualified default super call
|
||||||
*/
|
*/
|
||||||
|
@ -129,7 +129,7 @@ public class AttrContext {
|
||||||
info.lint = lint;
|
info.lint = lint;
|
||||||
info.enclVar = enclVar;
|
info.enclVar = enclVar;
|
||||||
info.returnResult = returnResult;
|
info.returnResult = returnResult;
|
||||||
info.breakResult = breakResult;
|
info.yieldResult = yieldResult;
|
||||||
info.defaultSuperCallSite = defaultSuperCallSite;
|
info.defaultSuperCallSite = defaultSuperCallSite;
|
||||||
info.isSerializable = isSerializable;
|
info.isSerializable = isSerializable;
|
||||||
info.isLambda = isLambda;
|
info.isLambda = isLambda;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2019, 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
|
||||||
|
@ -1161,7 +1161,7 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||||
|
|
||||||
SwitchExpressionScanner() {
|
SwitchExpressionScanner() {
|
||||||
super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP,
|
super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP,
|
||||||
FORLOOP, IF, BREAK, SYNCHRONIZED, SWITCH, TRY, WHILELOOP));
|
FORLOOP, IF, SYNCHRONIZED, SWITCH, TRY, WHILELOOP, YIELD));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -314,6 +314,12 @@ public class Flow {
|
||||||
JCTree getTarget(JCTree tree) {
|
JCTree getTarget(JCTree tree) {
|
||||||
return ((JCContinue)tree).target;
|
return ((JCContinue)tree).target;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
YIELD(JCTree.Tag.YIELD) {
|
||||||
|
@Override
|
||||||
|
JCTree getTarget(JCTree tree) {
|
||||||
|
return ((JCYield)tree).target;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final JCTree.Tag treeTag;
|
final JCTree.Tag treeTag;
|
||||||
|
@ -386,6 +392,11 @@ public class Flow {
|
||||||
return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
|
return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resolve all yields of this statement. */
|
||||||
|
Liveness resolveYields(JCTree tree, ListBuffer<PendingExit> oldPendingExits) {
|
||||||
|
return resolveJump(tree, oldPendingExits, JumpKind.YIELD);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scan(JCTree tree) {
|
public void scan(JCTree tree) {
|
||||||
if (tree != null && (
|
if (tree != null && (
|
||||||
|
@ -400,9 +411,15 @@ public class Flow {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void scanSyntheticBreak(TreeMaker make, JCTree swtch) {
|
protected void scanSyntheticBreak(TreeMaker make, JCTree swtch) {
|
||||||
JCBreak brk = make.at(Position.NOPOS).Break(null);
|
if (swtch.hasTag(SWITCH_EXPRESSION)) {
|
||||||
brk.target = swtch;
|
JCYield brk = make.at(Position.NOPOS).Yield(null);
|
||||||
scan(brk);
|
brk.target = swtch;
|
||||||
|
scan(brk);
|
||||||
|
} else {
|
||||||
|
JCBreak brk = make.at(Position.NOPOS).Break(null);
|
||||||
|
brk.target = swtch;
|
||||||
|
scan(brk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +534,8 @@ public class Flow {
|
||||||
while (exits.nonEmpty()) {
|
while (exits.nonEmpty()) {
|
||||||
PendingExit exit = exits.head;
|
PendingExit exit = exits.head;
|
||||||
exits = exits.tail;
|
exits = exits.tail;
|
||||||
Assert.check(exit.tree.hasTag(RETURN));
|
Assert.check(exit.tree.hasTag(RETURN) ||
|
||||||
|
log.hasErrorOn(exit.tree.pos()));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
lint = lintPrev;
|
lint = lintPrev;
|
||||||
|
@ -677,7 +695,7 @@ public class Flow {
|
||||||
log.error(tree, Errors.NotExhaustive);
|
log.error(tree, Errors.NotExhaustive);
|
||||||
}
|
}
|
||||||
alive = prevAlive;
|
alive = prevAlive;
|
||||||
alive = alive.or(resolveBreaks(tree, prevPendingExits));
|
alive = alive.or(resolveYields(tree, prevPendingExits));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitTry(JCTry tree) {
|
public void visitTry(JCTry tree) {
|
||||||
|
@ -745,8 +763,12 @@ public class Flow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (tree.isValueBreak())
|
recordExit(new PendingExit(tree));
|
||||||
scan(tree.value);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
scan(tree.value);
|
||||||
recordExit(new PendingExit(tree));
|
recordExit(new PendingExit(tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1032,7 +1054,8 @@ public class Flow {
|
||||||
PendingExit exit = exits.head;
|
PendingExit exit = exits.head;
|
||||||
exits = exits.tail;
|
exits = exits.tail;
|
||||||
if (!(exit instanceof ThrownPendingExit)) {
|
if (!(exit instanceof ThrownPendingExit)) {
|
||||||
Assert.check(exit.tree.hasTag(RETURN));
|
Assert.check(exit.tree.hasTag(RETURN) ||
|
||||||
|
log.hasErrorOn(exit.tree.pos()));
|
||||||
} else {
|
} else {
|
||||||
// uncaught throws will be reported later
|
// uncaught throws will be reported later
|
||||||
pendingExits.append(exit);
|
pendingExits.append(exit);
|
||||||
|
@ -1126,7 +1149,11 @@ public class Flow {
|
||||||
scan(c.pats);
|
scan(c.pats);
|
||||||
scan(c.stats);
|
scan(c.stats);
|
||||||
}
|
}
|
||||||
resolveBreaks(tree, prevPendingExits);
|
if (tree.hasTag(SWITCH_EXPRESSION)) {
|
||||||
|
resolveYields(tree, prevPendingExits);
|
||||||
|
} else {
|
||||||
|
resolveBreaks(tree, prevPendingExits);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitTry(JCTry tree) {
|
public void visitTry(JCTry tree) {
|
||||||
|
@ -1267,8 +1294,11 @@ public class Flow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (tree.isValueBreak())
|
recordExit(new PendingExit(tree));
|
||||||
scan(tree.value);
|
}
|
||||||
|
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
scan(tree.value);
|
||||||
recordExit(new PendingExit(tree));
|
recordExit(new PendingExit(tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1357,7 +1387,8 @@ public class Flow {
|
||||||
PendingExit exit = exits.head;
|
PendingExit exit = exits.head;
|
||||||
exits = exits.tail;
|
exits = exits.tail;
|
||||||
if (!(exit instanceof ThrownPendingExit)) {
|
if (!(exit instanceof ThrownPendingExit)) {
|
||||||
Assert.check(exit.tree.hasTag(RETURN));
|
Assert.check(exit.tree.hasTag(RETURN) ||
|
||||||
|
log.hasErrorOn(exit.tree.pos()));
|
||||||
} else {
|
} else {
|
||||||
// uncaught throws will be reported later
|
// uncaught throws will be reported later
|
||||||
pendingExits.append(exit);
|
pendingExits.append(exit);
|
||||||
|
@ -1977,7 +2008,9 @@ public class Flow {
|
||||||
while (exits.nonEmpty()) {
|
while (exits.nonEmpty()) {
|
||||||
PendingExit exit = exits.head;
|
PendingExit exit = exits.head;
|
||||||
exits = exits.tail;
|
exits = exits.tail;
|
||||||
Assert.check(exit.tree.hasTag(RETURN), exit.tree);
|
Assert.check(exit.tree.hasTag(RETURN) ||
|
||||||
|
log.hasErrorOn(exit.tree.pos()),
|
||||||
|
exit.tree);
|
||||||
if (isInitialConstructor) {
|
if (isInitialConstructor) {
|
||||||
Assert.check(exit instanceof AssignPendingExit);
|
Assert.check(exit instanceof AssignPendingExit);
|
||||||
inits.assign(((AssignPendingExit) exit).exit_inits);
|
inits.assign(((AssignPendingExit) exit).exit_inits);
|
||||||
|
@ -2232,7 +2265,11 @@ public class Flow {
|
||||||
inits.andSet(initsSwitch);
|
inits.andSet(initsSwitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolveBreaks(tree, prevPendingExits);
|
if (tree.hasTag(SWITCH_EXPRESSION)) {
|
||||||
|
resolveYields(tree, prevPendingExits);
|
||||||
|
} else {
|
||||||
|
resolveBreaks(tree, prevPendingExits);
|
||||||
|
}
|
||||||
nextadr = nextadrPrev;
|
nextadr = nextadrPrev;
|
||||||
}
|
}
|
||||||
// where
|
// where
|
||||||
|
@ -2397,37 +2434,39 @@ public class Flow {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (tree.isValueBreak()) {
|
|
||||||
if (tree.target.hasTag(SWITCH_EXPRESSION)) {
|
|
||||||
JCSwitchExpression expr = (JCSwitchExpression) tree.target;
|
|
||||||
if (expr.type.hasTag(BOOLEAN)) {
|
|
||||||
scanCond(tree.value);
|
|
||||||
Bits initsAfterBreakWhenTrue = new Bits(initsWhenTrue);
|
|
||||||
Bits initsAfterBreakWhenFalse = new Bits(initsWhenFalse);
|
|
||||||
Bits uninitsAfterBreakWhenTrue = new Bits(uninitsWhenTrue);
|
|
||||||
Bits uninitsAfterBreakWhenFalse = new Bits(uninitsWhenFalse);
|
|
||||||
PendingExit exit = new PendingExit(tree) {
|
|
||||||
@Override
|
|
||||||
void resolveJump() {
|
|
||||||
if (!inits.isReset()) {
|
|
||||||
split(true);
|
|
||||||
}
|
|
||||||
initsWhenTrue.andSet(initsAfterBreakWhenTrue);
|
|
||||||
initsWhenFalse.andSet(initsAfterBreakWhenFalse);
|
|
||||||
uninitsWhenTrue.andSet(uninitsAfterBreakWhenTrue);
|
|
||||||
uninitsWhenFalse.andSet(uninitsAfterBreakWhenFalse);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
merge();
|
|
||||||
recordExit(exit);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scan(tree.value);
|
|
||||||
}
|
|
||||||
recordExit(new AssignPendingExit(tree, inits, uninits));
|
recordExit(new AssignPendingExit(tree, inits, uninits));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
JCSwitchExpression expr = (JCSwitchExpression) tree.target;
|
||||||
|
if (expr != null && expr.type.hasTag(BOOLEAN)) {
|
||||||
|
scanCond(tree.value);
|
||||||
|
Bits initsAfterBreakWhenTrue = new Bits(initsWhenTrue);
|
||||||
|
Bits initsAfterBreakWhenFalse = new Bits(initsWhenFalse);
|
||||||
|
Bits uninitsAfterBreakWhenTrue = new Bits(uninitsWhenTrue);
|
||||||
|
Bits uninitsAfterBreakWhenFalse = new Bits(uninitsWhenFalse);
|
||||||
|
PendingExit exit = new PendingExit(tree) {
|
||||||
|
@Override
|
||||||
|
void resolveJump() {
|
||||||
|
if (!inits.isReset()) {
|
||||||
|
split(true);
|
||||||
|
}
|
||||||
|
initsWhenTrue.andSet(initsAfterBreakWhenTrue);
|
||||||
|
initsWhenFalse.andSet(initsAfterBreakWhenFalse);
|
||||||
|
uninitsWhenTrue.andSet(uninitsAfterBreakWhenTrue);
|
||||||
|
uninitsWhenFalse.andSet(uninitsAfterBreakWhenFalse);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
merge();
|
||||||
|
recordExit(exit);
|
||||||
|
return ;
|
||||||
|
} else {
|
||||||
|
scan(tree.value);
|
||||||
|
recordExit(new AssignPendingExit(tree, inits, uninits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitContinue(JCContinue tree) {
|
public void visitContinue(JCContinue tree) {
|
||||||
recordExit(new AssignPendingExit(tree, inits, uninits));
|
recordExit(new AssignPendingExit(tree, inits, uninits));
|
||||||
|
@ -2788,9 +2827,8 @@ public class Flow {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitYield(JCYield tree) {
|
||||||
if (tree.isValueBreak())
|
scan(tree.value);
|
||||||
scan(tree.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitModuleDef(JCModuleDecl tree) {
|
public void visitModuleDef(JCModuleDecl tree) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -272,9 +272,8 @@ public class Lower extends TreeTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitYield(JCYield tree) {
|
||||||
if (tree.isValueBreak())
|
scan(tree.value);
|
||||||
scan(tree.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1887,7 +1886,7 @@ public class Lower extends TreeTranslator {
|
||||||
ClassSymbol c = types.boxedClass(type);
|
ClassSymbol c = types.boxedClass(type);
|
||||||
Symbol typeSym =
|
Symbol typeSym =
|
||||||
rs.accessBase(
|
rs.accessBase(
|
||||||
rs.findIdentInType(attrEnv, c.type, names.TYPE, KindSelector.VAR),
|
rs.findIdentInType(pos, attrEnv, c.type, names.TYPE, KindSelector.VAR),
|
||||||
pos, c.type, names.TYPE, true);
|
pos, c.type, names.TYPE, true);
|
||||||
if (typeSym.kind == VAR)
|
if (typeSym.kind == VAR)
|
||||||
((VarSymbol)typeSym).getConstValue(); // ensure initializer is evaluated
|
((VarSymbol)typeSym).getConstValue(); // ensure initializer is evaluated
|
||||||
|
@ -3224,6 +3223,11 @@ public class Lower extends TreeTranslator {
|
||||||
if (tree.target == src)
|
if (tree.target == src)
|
||||||
tree.target = dest;
|
tree.target = dest;
|
||||||
}
|
}
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
if (tree.target == src)
|
||||||
|
tree.target = dest;
|
||||||
|
scan(tree.value);
|
||||||
|
}
|
||||||
public void visitContinue(JCContinue tree) {
|
public void visitContinue(JCContinue tree) {
|
||||||
if (tree.target == src)
|
if (tree.target == src)
|
||||||
tree.target = dest;
|
tree.target = dest;
|
||||||
|
@ -3676,9 +3680,12 @@ public class Lower extends TreeTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (tree.isValueBreak()) {
|
result = tree;
|
||||||
tree.value = translate(tree.value, tree.target.type);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
tree.value = translate(tree.value, tree.target.type);
|
||||||
result = tree;
|
result = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ public class MemberEnter extends JCTree.Visitor {
|
||||||
tree.sym.type.getReturnType());
|
tree.sym.type.getReturnType());
|
||||||
}
|
}
|
||||||
if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
|
if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
|
||||||
localEnv.info.breakResult = null;
|
localEnv.info.yieldResult = null;
|
||||||
return localEnv;
|
return localEnv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ import com.sun.tools.javac.jvm.*;
|
||||||
import com.sun.tools.javac.main.Option;
|
import com.sun.tools.javac.main.Option;
|
||||||
import com.sun.tools.javac.resources.CompilerProperties.Errors;
|
import com.sun.tools.javac.resources.CompilerProperties.Errors;
|
||||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||||
|
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
|
||||||
import com.sun.tools.javac.tree.*;
|
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.tree.JCTree.JCMemberReference.ReferenceKind;
|
import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
|
||||||
|
@ -52,6 +53,7 @@ import com.sun.tools.javac.util.DefinedBy.Api;
|
||||||
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.DiagnosticPosition;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
|
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic.Warning;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -63,6 +65,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -105,6 +108,7 @@ public class Resolve {
|
||||||
public final boolean checkVarargsAccessAfterResolution;
|
public final boolean checkVarargsAccessAfterResolution;
|
||||||
private final boolean compactMethodDiags;
|
private final boolean compactMethodDiags;
|
||||||
private final boolean allowLocalVariableTypeInference;
|
private final boolean allowLocalVariableTypeInference;
|
||||||
|
private final boolean allowYieldStatement;
|
||||||
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
|
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
|
||||||
|
|
||||||
WriteableScope polymorphicSignatureScope;
|
WriteableScope polymorphicSignatureScope;
|
||||||
|
@ -128,6 +132,7 @@ public class Resolve {
|
||||||
moduleFinder = ModuleFinder.instance(context);
|
moduleFinder = ModuleFinder.instance(context);
|
||||||
types = Types.instance(context);
|
types = Types.instance(context);
|
||||||
diags = JCDiagnostic.Factory.instance(context);
|
diags = JCDiagnostic.Factory.instance(context);
|
||||||
|
Preview preview = Preview.instance(context);
|
||||||
Source source = Source.instance(context);
|
Source source = Source.instance(context);
|
||||||
Options options = Options.instance(context);
|
Options options = Options.instance(context);
|
||||||
compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
|
compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
|
||||||
|
@ -136,6 +141,8 @@ public class Resolve {
|
||||||
Target target = Target.instance(context);
|
Target target = Target.instance(context);
|
||||||
allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source);
|
allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source);
|
||||||
allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
|
allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
|
||||||
|
allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) &&
|
||||||
|
Feature.SWITCH_EXPRESSION.allowedInSource(source);
|
||||||
checkVarargsAccessAfterResolution =
|
checkVarargsAccessAfterResolution =
|
||||||
Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source);
|
Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source);
|
||||||
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
|
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
|
||||||
|
@ -2330,13 +2337,15 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find an unqualified identifier which matches a specified kind set.
|
/** Find an unqualified identifier which matches a specified kind set.
|
||||||
|
* @param pos position on which report warnings, if any;
|
||||||
|
* null warnings should not be reported
|
||||||
* @param env The current environment.
|
* @param env The current environment.
|
||||||
* @param name The identifier's name.
|
* @param name The identifier's name.
|
||||||
* @param kind Indicates the possible symbol kinds
|
* @param kind Indicates the possible symbol kinds
|
||||||
* (a subset of VAL, TYP, PCK).
|
* (a subset of VAL, TYP, PCK).
|
||||||
*/
|
*/
|
||||||
Symbol findIdent(Env<AttrContext> env, Name name, KindSelector kind) {
|
Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
|
||||||
return checkVarType(findIdentInternal(env, name, kind), name);
|
return checkRestrictedType(pos, findIdentInternal(env, name, kind), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol findIdentInternal(Env<AttrContext> env, Name name, KindSelector kind) {
|
Symbol findIdentInternal(Env<AttrContext> env, Name name, KindSelector kind) {
|
||||||
|
@ -2362,14 +2371,17 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find an identifier in a package which matches a specified kind set.
|
/** Find an identifier in a package which matches a specified kind set.
|
||||||
|
* @param pos position on which report warnings, if any;
|
||||||
|
* null warnings should not be reported
|
||||||
* @param env The current environment.
|
* @param env The current environment.
|
||||||
* @param name The identifier's name.
|
* @param name The identifier's name.
|
||||||
* @param kind Indicates the possible symbol kinds
|
* @param kind Indicates the possible symbol kinds
|
||||||
* (a nonempty subset of TYP, PCK).
|
* (a nonempty subset of TYP, PCK).
|
||||||
*/
|
*/
|
||||||
Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
|
Symbol findIdentInPackage(DiagnosticPosition pos,
|
||||||
|
Env<AttrContext> env, TypeSymbol pck,
|
||||||
Name name, KindSelector kind) {
|
Name name, KindSelector kind) {
|
||||||
return checkVarType(findIdentInPackageInternal(env, pck, name, kind), name);
|
return checkRestrictedType(pos, findIdentInPackageInternal(env, pck, name, kind), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck,
|
Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck,
|
||||||
|
@ -2395,15 +2407,18 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find an identifier among the members of a given type `site'.
|
/** Find an identifier among the members of a given type `site'.
|
||||||
|
* @param pos position on which report warnings, if any;
|
||||||
|
* null warnings should not be reported
|
||||||
* @param env The current environment.
|
* @param env The current environment.
|
||||||
* @param site The type containing the symbol to be found.
|
* @param site The type containing the symbol to be found.
|
||||||
* @param name The identifier's name.
|
* @param name The identifier's name.
|
||||||
* @param kind Indicates the possible symbol kinds
|
* @param kind Indicates the possible symbol kinds
|
||||||
* (a subset of VAL, TYP).
|
* (a subset of VAL, TYP).
|
||||||
*/
|
*/
|
||||||
Symbol findIdentInType(Env<AttrContext> env, Type site,
|
Symbol findIdentInType(DiagnosticPosition pos,
|
||||||
|
Env<AttrContext> env, Type site,
|
||||||
Name name, KindSelector kind) {
|
Name name, KindSelector kind) {
|
||||||
return checkVarType(findIdentInTypeInternal(env, site, name, kind), name);
|
return checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
|
Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
|
||||||
|
@ -2424,10 +2439,17 @@ public class Resolve {
|
||||||
return bestSoFar;
|
return bestSoFar;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Symbol checkVarType(Symbol bestSoFar, Name name) {
|
private Symbol checkRestrictedType(DiagnosticPosition pos, Symbol bestSoFar, Name name) {
|
||||||
if (allowLocalVariableTypeInference && name.equals(names.var) &&
|
if (bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP) {
|
||||||
(bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP)) {
|
if (allowLocalVariableTypeInference && name.equals(names.var)) {
|
||||||
bestSoFar = new BadVarTypeError();
|
bestSoFar = new BadRestrictedTypeError(names.var);
|
||||||
|
} else if (name.equals(names.yield)) {
|
||||||
|
if (allowYieldStatement) {
|
||||||
|
bestSoFar = new BadRestrictedTypeError(names.yield);
|
||||||
|
} else if (pos != null) {
|
||||||
|
log.warning(pos, Warnings.IllegalRefToRestrictedType(names.yield));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return bestSoFar;
|
return bestSoFar;
|
||||||
}
|
}
|
||||||
|
@ -2597,7 +2619,7 @@ public class Resolve {
|
||||||
Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
|
Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
|
||||||
Name name, KindSelector kind) {
|
Name name, KindSelector kind) {
|
||||||
return accessBase(
|
return accessBase(
|
||||||
findIdent(env, name, kind),
|
findIdent(pos, env, name, kind),
|
||||||
pos, env.enclClass.sym.type, name, false);
|
pos, env.enclClass.sym.type, name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3833,14 +3855,16 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BadVarTypeError extends ResolveError {
|
class BadRestrictedTypeError extends ResolveError {
|
||||||
BadVarTypeError() {
|
private final Name typeName;
|
||||||
super(Kind.BAD_VAR, "bad var use");
|
BadRestrictedTypeError(Name typeName) {
|
||||||
|
super(Kind.BAD_RESTRICTED_TYPE, "bad var use");
|
||||||
|
this.typeName = typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
|
JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
|
||||||
return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.var.type");
|
return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -620,11 +620,14 @@ public class TransTypes extends TreeTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (tree.isValueBreak()) {
|
result = tree;
|
||||||
tree.value = translate(tree.value, erasure(tree.value.type));
|
}
|
||||||
tree.value.type = erasure(tree.value.type);
|
|
||||||
tree.value = retype(tree.value, tree.value.type, pt);
|
@Override
|
||||||
}
|
public void visitYield(JCYield tree) {
|
||||||
|
tree.value = translate(tree.value, erasure(tree.value.type));
|
||||||
|
tree.value.type = erasure(tree.value.type);
|
||||||
|
tree.value = retype(tree.value, tree.value.type, pt);
|
||||||
result = tree;
|
result = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ import com.sun.tools.javac.tree.JCTree.JCProvides;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCRequires;
|
import com.sun.tools.javac.tree.JCTree.JCRequires;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCReturn;
|
import com.sun.tools.javac.tree.JCTree.JCReturn;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCSwitch;
|
import com.sun.tools.javac.tree.JCTree.JCSwitch;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCSynchronized;
|
import com.sun.tools.javac.tree.JCTree.JCSynchronized;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCThrow;
|
import com.sun.tools.javac.tree.JCTree.JCThrow;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCTry;
|
import com.sun.tools.javac.tree.JCTree.JCTry;
|
||||||
|
@ -84,6 +85,7 @@ import com.sun.tools.javac.tree.JCTree.JCUses;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
|
import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCWildcard;
|
import com.sun.tools.javac.tree.JCTree.JCWildcard;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCYield;
|
||||||
import com.sun.tools.javac.tree.JCTree.LetExpr;
|
import com.sun.tools.javac.tree.JCTree.LetExpr;
|
||||||
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
|
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
|
||||||
import com.sun.tools.javac.tree.TreeInfo;
|
import com.sun.tools.javac.tree.TreeInfo;
|
||||||
|
@ -259,6 +261,12 @@ public class TreeDiffer extends TreeScanner {
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
JCBreak that = (JCBreak) parameter;
|
JCBreak that = (JCBreak) parameter;
|
||||||
|
result = tree.label == that.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
JCYield that = (JCYield) parameter;
|
||||||
result = scan(tree.value, that.value);
|
result = scan(tree.value, that.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +506,12 @@ public class TreeDiffer extends TreeScanner {
|
||||||
result = scan(tree.selector, that.selector) && scan(tree.cases, that.cases);
|
result = scan(tree.selector, that.selector) && scan(tree.cases, that.cases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSwitchExpression(JCSwitchExpression tree) {
|
||||||
|
JCSwitchExpression that = (JCSwitchExpression) parameter;
|
||||||
|
result = scan(tree.selector, that.selector) && scan(tree.cases, that.cases);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitSynchronized(JCSynchronized tree) {
|
public void visitSynchronized(JCSynchronized tree) {
|
||||||
JCSynchronized that = (JCSynchronized) parameter;
|
JCSynchronized that = (JCSynchronized) parameter;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2019, 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
|
||||||
|
@ -377,6 +377,11 @@ implements CRTFlags {
|
||||||
result = sr;
|
result = sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
|
||||||
|
result = sr;
|
||||||
|
}
|
||||||
|
|
||||||
public void visitContinue(JCContinue tree) {
|
public void visitContinue(JCContinue tree) {
|
||||||
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
|
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
|
||||||
result = sr;
|
result = sr;
|
||||||
|
|
|
@ -1716,47 +1716,49 @@ public class Gen extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
|
Assert.check(code.isStatementStart());
|
||||||
|
final Env<GenContext> targetEnv = unwindBreak(tree.target);
|
||||||
|
targetEnv.info.addExit(code.branch(goto_));
|
||||||
|
endFinalizerGaps(env, targetEnv);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
Assert.check(code.isStatementStart());
|
Assert.check(code.isStatementStart());
|
||||||
final Env<GenContext> targetEnv;
|
final Env<GenContext> targetEnv;
|
||||||
if (tree.isValueBreak()) {
|
//restore stack as it was before the switch expression:
|
||||||
//restore stack as it was before the switch expression:
|
for (LocalItem li : stackBeforeSwitchExpression) {
|
||||||
for (LocalItem li : stackBeforeSwitchExpression) {
|
li.load();
|
||||||
li.load();
|
}
|
||||||
}
|
if (inCondSwitchExpression) {
|
||||||
if (inCondSwitchExpression) {
|
CondItem value = genCond(tree.value, CRT_FLOW_TARGET);
|
||||||
CondItem value = genCond(tree.value, CRT_FLOW_TARGET);
|
Chain falseJumps = value.jumpFalse();
|
||||||
Chain falseJumps = value.jumpFalse();
|
targetEnv = unwindBreak(tree.target);
|
||||||
targetEnv = unwindBreak(tree);
|
code.resolve(value.trueJumps);
|
||||||
code.resolve(value.trueJumps);
|
Chain trueJumps = code.branch(goto_);
|
||||||
Chain trueJumps = code.branch(goto_);
|
if (switchExpressionTrueChain == null) {
|
||||||
if (switchExpressionTrueChain == null) {
|
switchExpressionTrueChain = trueJumps;
|
||||||
switchExpressionTrueChain = trueJumps;
|
|
||||||
} else {
|
|
||||||
switchExpressionTrueChain =
|
|
||||||
Code.mergeChains(switchExpressionTrueChain, trueJumps);
|
|
||||||
}
|
|
||||||
if (switchExpressionFalseChain == null) {
|
|
||||||
switchExpressionFalseChain = falseJumps;
|
|
||||||
} else {
|
|
||||||
switchExpressionFalseChain =
|
|
||||||
Code.mergeChains(switchExpressionFalseChain, falseJumps);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
genExpr(tree.value, pt).load();
|
switchExpressionTrueChain =
|
||||||
code.state.forceStackTop(tree.target.type);
|
Code.mergeChains(switchExpressionTrueChain, trueJumps);
|
||||||
targetEnv = unwindBreak(tree);
|
}
|
||||||
targetEnv.info.addExit(code.branch(goto_));
|
if (switchExpressionFalseChain == null) {
|
||||||
|
switchExpressionFalseChain = falseJumps;
|
||||||
|
} else {
|
||||||
|
switchExpressionFalseChain =
|
||||||
|
Code.mergeChains(switchExpressionFalseChain, falseJumps);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targetEnv = unwindBreak(tree);
|
genExpr(tree.value, pt).load();
|
||||||
|
code.state.forceStackTop(tree.target.type);
|
||||||
|
targetEnv = unwindBreak(tree.target);
|
||||||
targetEnv.info.addExit(code.branch(goto_));
|
targetEnv.info.addExit(code.branch(goto_));
|
||||||
}
|
}
|
||||||
endFinalizerGaps(env, targetEnv);
|
endFinalizerGaps(env, targetEnv);
|
||||||
}
|
}
|
||||||
//where:
|
//where:
|
||||||
private Env<GenContext> unwindBreak(JCBreak tree) {
|
private Env<GenContext> unwindBreak(JCTree target) {
|
||||||
int tmpPos = code.pendingStatPos;
|
int tmpPos = code.pendingStatPos;
|
||||||
Env<GenContext> targetEnv = unwind(tree.target, env);
|
Env<GenContext> targetEnv = unwind(target, env);
|
||||||
code.pendingStatPos = tmpPos;
|
code.pendingStatPos = tmpPos;
|
||||||
return targetEnv;
|
return targetEnv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -182,6 +182,8 @@ public class JavacParser implements Parser {
|
||||||
this.keepLineMap = keepLineMap;
|
this.keepLineMap = keepLineMap;
|
||||||
this.errorTree = F.Erroneous();
|
this.errorTree = F.Erroneous();
|
||||||
endPosTable = newEndPosTable(keepEndPositions);
|
endPosTable = newEndPosTable(keepEndPositions);
|
||||||
|
this.allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) &&
|
||||||
|
Feature.SWITCH_EXPRESSION.allowedInSource(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
|
protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
|
||||||
|
@ -211,6 +213,10 @@ public class JavacParser implements Parser {
|
||||||
*/
|
*/
|
||||||
boolean allowThisIdent;
|
boolean allowThisIdent;
|
||||||
|
|
||||||
|
/** Switch: is yield statement allowed in this source level?
|
||||||
|
*/
|
||||||
|
boolean allowYieldStatement;
|
||||||
|
|
||||||
/** The type of the method receiver, as specified by a first "this" parameter.
|
/** The type of the method receiver, as specified by a first "this" parameter.
|
||||||
*/
|
*/
|
||||||
JCVariableDecl receiverParam;
|
JCVariableDecl receiverParam;
|
||||||
|
@ -769,9 +775,10 @@ public class JavacParser implements Parser {
|
||||||
|
|
||||||
public JCExpression unannotatedType(boolean allowVar) {
|
public JCExpression unannotatedType(boolean allowVar) {
|
||||||
JCExpression result = term(TYPE);
|
JCExpression result = term(TYPE);
|
||||||
|
Name restrictedTypeName;
|
||||||
|
|
||||||
if (!allowVar && isRestrictedLocalVarTypeName(result, true)) {
|
if (!allowVar && (restrictedTypeName = restrictedTypeName(result, true)) != null) {
|
||||||
syntaxError(result.pos, Errors.VarNotAllowedHere);
|
syntaxError(result.pos, Errors.RestrictedTypeNotAllowedHere(restrictedTypeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1377,6 +1384,7 @@ public class JavacParser implements Parser {
|
||||||
break;
|
break;
|
||||||
case SWITCH:
|
case SWITCH:
|
||||||
checkSourceLevel(Feature.SWITCH_EXPRESSION);
|
checkSourceLevel(Feature.SWITCH_EXPRESSION);
|
||||||
|
allowYieldStatement = true;
|
||||||
int switchPos = token.pos;
|
int switchPos = token.pos;
|
||||||
nextToken();
|
nextToken();
|
||||||
JCExpression selector = parExpression();
|
JCExpression selector = parExpression();
|
||||||
|
@ -1436,7 +1444,7 @@ public class JavacParser implements Parser {
|
||||||
kind = JCCase.RULE;
|
kind = JCCase.RULE;
|
||||||
} else {
|
} else {
|
||||||
JCExpression value = parseExpression();
|
JCExpression value = parseExpression();
|
||||||
stats = List.of(to(F.at(value).Break(value)));
|
stats = List.of(to(F.at(value).Yield(value)));
|
||||||
body = value;
|
body = value;
|
||||||
kind = JCCase.RULE;
|
kind = JCCase.RULE;
|
||||||
accept(SEMI);
|
accept(SEMI);
|
||||||
|
@ -1607,7 +1615,7 @@ public class JavacParser implements Parser {
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
boolean type = false;
|
boolean type = false;
|
||||||
ParensResult defaultResult = ParensResult.PARENS;
|
ParensResult defaultResult = ParensResult.PARENS;
|
||||||
outer: for (int lookahead = 0 ; ; lookahead++) {
|
outer: for (int lookahead = 0; ; lookahead++) {
|
||||||
TokenKind tk = S.token(lookahead).kind;
|
TokenKind tk = S.token(lookahead).kind;
|
||||||
switch (tk) {
|
switch (tk) {
|
||||||
case COMMA:
|
case COMMA:
|
||||||
|
@ -1782,12 +1790,13 @@ public class JavacParser implements Parser {
|
||||||
if (explicitParams) {
|
if (explicitParams) {
|
||||||
LambdaClassifier lambdaClassifier = new LambdaClassifier();
|
LambdaClassifier lambdaClassifier = new LambdaClassifier();
|
||||||
for (JCVariableDecl param: params) {
|
for (JCVariableDecl param: params) {
|
||||||
|
Name restrictedTypeName;
|
||||||
if (param.vartype != null &&
|
if (param.vartype != null &&
|
||||||
isRestrictedLocalVarTypeName(param.vartype, false) &&
|
(restrictedTypeName = restrictedTypeName(param.vartype, false)) != null &&
|
||||||
param.vartype.hasTag(TYPEARRAY)) {
|
param.vartype.hasTag(TYPEARRAY)) {
|
||||||
log.error(DiagnosticFlag.SYNTAX, param.pos,
|
log.error(DiagnosticFlag.SYNTAX, param.pos,
|
||||||
Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source)
|
Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source)
|
||||||
? Errors.VarNotAllowedArray : Errors.VarNotAllowedHere);
|
? Errors.RestrictedTypeNotAllowedArray(restrictedTypeName) : Errors.RestrictedTypeNotAllowedHere(restrictedTypeName));
|
||||||
}
|
}
|
||||||
lambdaClassifier.addParameter(param);
|
lambdaClassifier.addParameter(param);
|
||||||
if (lambdaClassifier.result() == LambdaParameterKind.ERROR) {
|
if (lambdaClassifier.result() == LambdaParameterKind.ERROR) {
|
||||||
|
@ -1799,7 +1808,7 @@ public class JavacParser implements Parser {
|
||||||
}
|
}
|
||||||
for (JCVariableDecl param: params) {
|
for (JCVariableDecl param: params) {
|
||||||
if (param.vartype != null
|
if (param.vartype != null
|
||||||
&& isRestrictedLocalVarTypeName(param.vartype, true)) {
|
&& restrictedTypeName(param.vartype, true) != null) {
|
||||||
checkSourceLevel(param.pos, Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS);
|
checkSourceLevel(param.pos, Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS);
|
||||||
param.startPos = TreeInfo.getStartPos(param.vartype);
|
param.startPos = TreeInfo.getStartPos(param.vartype);
|
||||||
param.vartype = null;
|
param.vartype = null;
|
||||||
|
@ -1837,7 +1846,7 @@ public class JavacParser implements Parser {
|
||||||
|
|
||||||
void addParameter(JCVariableDecl param) {
|
void addParameter(JCVariableDecl param) {
|
||||||
if (param.vartype != null && param.name != names.empty) {
|
if (param.vartype != null && param.name != names.empty) {
|
||||||
if (isRestrictedLocalVarTypeName(param.vartype, false)) {
|
if (restrictedTypeName(param.vartype, false) != null) {
|
||||||
reduce(LambdaParameterKind.VAR);
|
reduce(LambdaParameterKind.VAR);
|
||||||
} else {
|
} else {
|
||||||
reduce(LambdaParameterKind.EXPLICIT);
|
reduce(LambdaParameterKind.EXPLICIT);
|
||||||
|
@ -1944,10 +1953,27 @@ public class JavacParser implements Parser {
|
||||||
return args.toList();
|
return args.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
|
JCExpression arguments(List<JCExpression> typeArgs, JCExpression t) {
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
List<JCExpression> args = arguments();
|
List<JCExpression> args = arguments();
|
||||||
return toP(F.at(pos).Apply(typeArgs, t, args));
|
JCExpression mi = F.at(pos).Apply(typeArgs, t, args);
|
||||||
|
if (t.hasTag(IDENT) && isInvalidUnqualifiedMethodIdentifier(((JCIdent) t).pos,
|
||||||
|
((JCIdent) t).name)) {
|
||||||
|
log.error(DiagnosticFlag.SYNTAX, t, Errors.InvalidYield);
|
||||||
|
mi = F.Erroneous(List.of(mi));
|
||||||
|
}
|
||||||
|
return toP(mi);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isInvalidUnqualifiedMethodIdentifier(int pos, Name name) {
|
||||||
|
if (name == names.yield) {
|
||||||
|
if (allowYieldStatement) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.warning(pos, Warnings.InvalidYield);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TypeArgumentsOpt = [ TypeArguments ]
|
/** TypeArgumentsOpt = [ TypeArguments ]
|
||||||
|
@ -2506,6 +2532,7 @@ public class JavacParser implements Parser {
|
||||||
|
|
||||||
/**This method parses a statement appearing inside a block.
|
/**This method parses a statement appearing inside a block.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("fallthrough")
|
||||||
List<JCStatement> blockStatement() {
|
List<JCStatement> blockStatement() {
|
||||||
//todo: skip to anchor on error(?)
|
//todo: skip to anchor on error(?)
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
|
@ -2543,6 +2570,52 @@ public class JavacParser implements Parser {
|
||||||
log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
|
log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
|
||||||
dc = token.comment(CommentStyle.JAVADOC);
|
dc = token.comment(CommentStyle.JAVADOC);
|
||||||
return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
|
return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
|
||||||
|
case IDENTIFIER:
|
||||||
|
if (token.name() == names.yield && allowYieldStatement) {
|
||||||
|
Token next = S.token(1);
|
||||||
|
boolean isYieldStatement;
|
||||||
|
switch (next.kind) {
|
||||||
|
case PLUS: case SUB: case STRINGLITERAL: case CHARLITERAL:
|
||||||
|
case INTLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
|
||||||
|
case NULL: case IDENTIFIER: case TRUE: case FALSE:
|
||||||
|
case NEW: case SWITCH: case THIS: case SUPER:
|
||||||
|
isYieldStatement = true;
|
||||||
|
break;
|
||||||
|
case PLUSPLUS: case SUBSUB:
|
||||||
|
isYieldStatement = S.token(2).kind != SEMI;
|
||||||
|
break;
|
||||||
|
case LPAREN:
|
||||||
|
int lookahead = 2;
|
||||||
|
int balance = 1;
|
||||||
|
boolean hasComma = false;
|
||||||
|
Token l;
|
||||||
|
while ((l = S.token(lookahead)).kind != EOF && balance != 0) {
|
||||||
|
switch (l.kind) {
|
||||||
|
case LPAREN: balance++; break;
|
||||||
|
case RPAREN: balance--; break;
|
||||||
|
case COMMA: if (balance == 1) hasComma = true; break;
|
||||||
|
}
|
||||||
|
lookahead++;
|
||||||
|
}
|
||||||
|
isYieldStatement = (!hasComma && lookahead != 3) || l.kind == ARROW;
|
||||||
|
break;
|
||||||
|
case SEMI: //error recovery - this is not a valid statement:
|
||||||
|
isYieldStatement = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isYieldStatement = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isYieldStatement) {
|
||||||
|
nextToken();
|
||||||
|
JCExpression t = term(EXPR);
|
||||||
|
accept(SEMI);
|
||||||
|
return List.of(toP(F.at(pos).Yield(t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//else intentional fall-through
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
Token prevToken = token;
|
Token prevToken = token;
|
||||||
JCExpression t = term(EXPR | TYPE);
|
JCExpression t = term(EXPR | TYPE);
|
||||||
|
@ -2702,9 +2775,9 @@ public class JavacParser implements Parser {
|
||||||
}
|
}
|
||||||
case BREAK: {
|
case BREAK: {
|
||||||
nextToken();
|
nextToken();
|
||||||
JCExpression value = token.kind == SEMI ? null : parseExpression();
|
Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
|
||||||
accept(SEMI);
|
accept(SEMI);
|
||||||
JCBreak t = toP(F.at(pos).Break(value));
|
JCBreak t = toP(F.at(pos).Break(label));
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
case CONTINUE: {
|
case CONTINUE: {
|
||||||
|
@ -3181,14 +3254,14 @@ public class JavacParser implements Parser {
|
||||||
int startPos = Position.NOPOS;
|
int startPos = Position.NOPOS;
|
||||||
if (elemType.hasTag(IDENT)) {
|
if (elemType.hasTag(IDENT)) {
|
||||||
Name typeName = ((JCIdent)elemType).name;
|
Name typeName = ((JCIdent)elemType).name;
|
||||||
if (isRestrictedLocalVarTypeName(typeName, pos, !compound && localDecl)) {
|
if (isRestrictedTypeName(typeName, pos, !compound && localDecl)) {
|
||||||
if (type.hasTag(TYPEARRAY) && !compound) {
|
if (type.hasTag(TYPEARRAY) && !compound) {
|
||||||
//error - 'var' and arrays
|
//error - 'var' and arrays
|
||||||
reportSyntaxError(pos, Errors.VarNotAllowedArray);
|
reportSyntaxError(pos, Errors.RestrictedTypeNotAllowedArray(typeName));
|
||||||
} else {
|
} else {
|
||||||
if(compound)
|
if(compound)
|
||||||
//error - 'var' in compound local var decl
|
//error - 'var' in compound local var decl
|
||||||
reportSyntaxError(pos, Errors.VarNotAllowedCompound);
|
reportSyntaxError(pos, Errors.RestrictedTypeNotAllowedCompound(typeName));
|
||||||
startPos = TreeInfo.getStartPos(mods);
|
startPos = TreeInfo.getStartPos(mods);
|
||||||
if (startPos == Position.NOPOS)
|
if (startPos == Position.NOPOS)
|
||||||
startPos = TreeInfo.getStartPos(type);
|
startPos = TreeInfo.getStartPos(type);
|
||||||
|
@ -3204,23 +3277,30 @@ public class JavacParser implements Parser {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isRestrictedLocalVarTypeName(JCExpression e, boolean shouldWarn) {
|
Name restrictedTypeName(JCExpression e, boolean shouldWarn) {
|
||||||
switch (e.getTag()) {
|
switch (e.getTag()) {
|
||||||
case IDENT:
|
case IDENT:
|
||||||
return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos, shouldWarn);
|
return isRestrictedTypeName(((JCIdent)e).name, e.pos, shouldWarn) ? ((JCIdent)e).name : null;
|
||||||
case TYPEARRAY:
|
case TYPEARRAY:
|
||||||
return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn);
|
return restrictedTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn);
|
||||||
default:
|
default:
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isRestrictedLocalVarTypeName(Name name, int pos, boolean shouldWarn) {
|
boolean isRestrictedTypeName(Name name, int pos, boolean shouldWarn) {
|
||||||
if (name == names.var) {
|
if (name == names.var) {
|
||||||
if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
|
if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (shouldWarn) {
|
} else if (shouldWarn) {
|
||||||
log.warning(pos, Warnings.VarNotAllowed);
|
log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name == names.yield) {
|
||||||
|
if (allowYieldStatement) {
|
||||||
|
return true;
|
||||||
|
} else if (shouldWarn) {
|
||||||
|
log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK13));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3614,8 +3694,8 @@ public class JavacParser implements Parser {
|
||||||
Name typeName() {
|
Name typeName() {
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
Name name = ident();
|
Name name = ident();
|
||||||
if (isRestrictedLocalVarTypeName(name, pos, true)) {
|
if (isRestrictedTypeName(name, pos, true)) {
|
||||||
reportSyntaxError(pos, Errors.VarNotAllowed);
|
reportSyntaxError(pos, Errors.RestrictedTypeNotAllowed(name, name == names.var ? Source.JDK10 : Source.JDK13));
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,17 +188,14 @@ compiler.err.bad.initializer=\
|
||||||
compiler.err.break.outside.switch.loop=\
|
compiler.err.break.outside.switch.loop=\
|
||||||
break outside switch or loop
|
break outside switch or loop
|
||||||
|
|
||||||
compiler.err.break.missing.value=\
|
|
||||||
missing break value
|
|
||||||
|
|
||||||
compiler.err.break.outside.switch.expression=\
|
compiler.err.break.outside.switch.expression=\
|
||||||
break outside of enclosing switch expression
|
attempt to break out of a switch expression
|
||||||
|
|
||||||
compiler.err.continue.outside.switch.expression=\
|
compiler.err.continue.outside.switch.expression=\
|
||||||
continue outside of enclosing switch expression
|
attempt to continue out of a switch expression
|
||||||
|
|
||||||
compiler.err.return.outside.switch.expression=\
|
compiler.err.return.outside.switch.expression=\
|
||||||
return outside of enclosing switch expression
|
attempt to return out of a switch expression
|
||||||
|
|
||||||
compiler.err.rule.completes.normally=\
|
compiler.err.rule.completes.normally=\
|
||||||
switch rule completes without providing a value\n\
|
switch rule completes without providing a value\n\
|
||||||
|
@ -208,17 +205,20 @@ compiler.err.switch.expression.completes.normally=\
|
||||||
switch expression completes without providing a value\n\
|
switch expression completes without providing a value\n\
|
||||||
(switch expressions must either provide a value or throw for all possible input values)
|
(switch expressions must either provide a value or throw for all possible input values)
|
||||||
|
|
||||||
# 0: name
|
compiler.err.no.switch.expression =\
|
||||||
compiler.err.break.ambiguous.target=\
|
yield outside of switch expression
|
||||||
ambiguous reference to ''{0}''\n\
|
|
||||||
(''{0}'' is both a label and an expression)
|
|
||||||
|
|
||||||
# 0: tree tag
|
compiler.err.no.switch.expression.qualify=\
|
||||||
compiler.err.break.expr.not.immediate=\
|
yield outside of switch expression\n\
|
||||||
value break not supported in ''{0}''
|
(to invoke a method called yield, qualify the yield with a receiver or type name)
|
||||||
|
|
||||||
compiler.err.break.complex.value.no.switch.expression=\
|
compiler.err.invalid.yield=\
|
||||||
unexpected value break
|
invalid use of a restricted identifier ''yield''\n\
|
||||||
|
(to invoke a method called yield, qualify the yield with a receiver or type name)
|
||||||
|
|
||||||
|
compiler.warn.invalid.yield=\
|
||||||
|
''yield'' may become a restricted identifier in a future release\n\
|
||||||
|
(to invoke a method called yield, qualify the yield with a receiver or type name)
|
||||||
|
|
||||||
compiler.err.switch.expression.empty=\
|
compiler.err.switch.expression.empty=\
|
||||||
switch expression does not have any case clauses
|
switch expression does not have any case clauses
|
||||||
|
@ -1267,29 +1267,43 @@ compiler.err.io.exception=\
|
||||||
compiler.err.undef.label=\
|
compiler.err.undef.label=\
|
||||||
undefined label: {0}
|
undefined label: {0}
|
||||||
|
|
||||||
compiler.err.illegal.ref.to.var.type=\
|
# 0: name
|
||||||
illegal reference to restricted type ''var''
|
compiler.err.illegal.ref.to.restricted.type=\
|
||||||
|
illegal reference to restricted type ''{0}''
|
||||||
|
|
||||||
compiler.err.var.not.allowed=\
|
# 0: name
|
||||||
''var'' not allowed here\n\
|
compiler.warn.illegal.ref.to.restricted.type=\
|
||||||
as of release 10, ''var'' is a restricted local variable type and cannot be used for type declarations
|
illegal reference to restricted type ''{0}''
|
||||||
|
|
||||||
compiler.warn.var.not.allowed=\
|
# 0: name, 1: source
|
||||||
as of release 10, ''var'' is a restricted local variable type and cannot be used for type declarations or as the element type of an array
|
compiler.err.restricted.type.not.allowed=\
|
||||||
|
''{0}'' not allowed here\n\
|
||||||
|
as of release {1}, ''{0}'' is a restricted type name and cannot be used for type declarations
|
||||||
|
|
||||||
|
# 0: name, 1: source
|
||||||
|
compiler.warn.restricted.type.not.allowed=\
|
||||||
|
as of release {1}, ''{0}'' is a restricted type name and cannot be used for type declarations or as the element type of an array
|
||||||
|
|
||||||
|
# 0: name, 1: source
|
||||||
|
compiler.warn.restricted.type.not.allowed.preview=\
|
||||||
|
''{0}'' may become a restricted type name in a future release and may be unusable for type declarations or as the element type of an array
|
||||||
|
|
||||||
# 0: name (variable), 1: message segment
|
# 0: name (variable), 1: message segment
|
||||||
compiler.err.cant.infer.local.var.type=\
|
compiler.err.cant.infer.local.var.type=\
|
||||||
cannot infer type for local variable {0}\n\
|
cannot infer type for local variable {0}\n\
|
||||||
({1})
|
({1})
|
||||||
|
|
||||||
compiler.err.var.not.allowed.here=\
|
# 0: name
|
||||||
''var'' is not allowed here
|
compiler.err.restricted.type.not.allowed.here=\
|
||||||
|
''{0}'' is not allowed here
|
||||||
|
|
||||||
compiler.err.var.not.allowed.array=\
|
# 0: name
|
||||||
''var'' is not allowed as an element type of an array
|
compiler.err.restricted.type.not.allowed.array=\
|
||||||
|
''{0}'' is not allowed as an element type of an array
|
||||||
|
|
||||||
compiler.err.var.not.allowed.compound=\
|
# 0: name
|
||||||
''var'' is not allowed in a compound declaration
|
compiler.err.restricted.type.not.allowed.compound=\
|
||||||
|
''{0}'' is not allowed in a compound declaration
|
||||||
|
|
||||||
# 0: fragment
|
# 0: fragment
|
||||||
compiler.err.invalid.lambda.parameter.declaration=\
|
compiler.err.invalid.lambda.parameter.declaration=\
|
||||||
|
@ -2666,22 +2680,6 @@ compiler.misc.kindname.static.init=\
|
||||||
compiler.misc.kindname.instance.init=\
|
compiler.misc.kindname.instance.init=\
|
||||||
instance initializer
|
instance initializer
|
||||||
|
|
||||||
# the following are names of tree kinds:
|
|
||||||
compiler.misc.tree.tag.forloop=\
|
|
||||||
for
|
|
||||||
|
|
||||||
compiler.misc.tree.tag.foreachloop=\
|
|
||||||
for
|
|
||||||
|
|
||||||
compiler.misc.tree.tag.whileloop=\
|
|
||||||
while
|
|
||||||
|
|
||||||
compiler.misc.tree.tag.doloop=\
|
|
||||||
do
|
|
||||||
|
|
||||||
compiler.misc.tree.tag.switch=\
|
|
||||||
switch
|
|
||||||
|
|
||||||
#####
|
#####
|
||||||
|
|
||||||
compiler.misc.no.args=\
|
compiler.misc.no.args=\
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -187,6 +187,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
*/
|
*/
|
||||||
BREAK,
|
BREAK,
|
||||||
|
|
||||||
|
/** Yield statements, of type Yield.
|
||||||
|
*/
|
||||||
|
YIELD,
|
||||||
|
|
||||||
/** Continue statements, of type Continue.
|
/** Continue statements, of type Continue.
|
||||||
*/
|
*/
|
||||||
CONTINUE,
|
CONTINUE,
|
||||||
|
@ -1551,10 +1555,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
* A break from a loop or switch.
|
* A break from a loop or switch.
|
||||||
*/
|
*/
|
||||||
public static class JCBreak extends JCStatement implements BreakTree {
|
public static class JCBreak extends JCStatement implements BreakTree {
|
||||||
public JCExpression value;
|
public Name label;
|
||||||
public JCTree target;
|
public JCTree target;
|
||||||
protected JCBreak(JCExpression value, JCTree target) {
|
protected JCBreak(Name label, JCTree target) {
|
||||||
this.value = value;
|
this.label = label;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -1567,11 +1571,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
public Kind getKind() { return Kind.BREAK; }
|
public Kind getKind() { return Kind.BREAK; }
|
||||||
@DefinedBy(Api.COMPILER_TREE)
|
@DefinedBy(Api.COMPILER_TREE)
|
||||||
public Name getLabel() {
|
public Name getLabel() {
|
||||||
return value != null && value.getKind() == Kind.IDENTIFIER ? ((JCIdent) value).getName() : null;
|
return label;
|
||||||
}
|
}
|
||||||
@DefinedBy(Api.COMPILER_TREE)
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
public JCExpression getValue() { return value; }
|
|
||||||
@Override @DefinedBy(Api.COMPILER_TREE)
|
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||||
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
||||||
return v.visitBreak(this, d);
|
return v.visitBreak(this, d);
|
||||||
|
@ -1582,6 +1583,33 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A break-with from a switch expression.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
public static class JCYield extends JCStatement implements YieldTree {
|
||||||
|
public JCExpression value;
|
||||||
|
public JCTree target;
|
||||||
|
protected JCYield(JCExpression value, JCTree target) {
|
||||||
|
this.value = value;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor v) { v.visitYield(this); }
|
||||||
|
@DefinedBy(Api.COMPILER_TREE)
|
||||||
|
public Kind getKind() { return Kind.YIELD; }
|
||||||
|
@DefinedBy(Api.COMPILER_TREE)
|
||||||
|
public JCExpression getValue() { return value; }
|
||||||
|
@Override @DefinedBy(Api.COMPILER_TREE)
|
||||||
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
||||||
|
return v.visitYield(this, d);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Tag getTag() {
|
||||||
|
return YIELD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A continue of a loop.
|
* A continue of a loop.
|
||||||
*/
|
*/
|
||||||
|
@ -3091,7 +3119,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
JCExpression elsepart);
|
JCExpression elsepart);
|
||||||
JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart);
|
JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart);
|
||||||
JCExpressionStatement Exec(JCExpression expr);
|
JCExpressionStatement Exec(JCExpression expr);
|
||||||
JCBreak Break(JCExpression value);
|
JCBreak Break(Name label);
|
||||||
|
JCYield Yield(JCExpression value);
|
||||||
JCContinue Continue(Name label);
|
JCContinue Continue(Name label);
|
||||||
JCReturn Return(JCExpression expr);
|
JCReturn Return(JCExpression expr);
|
||||||
JCThrow Throw(JCExpression expr);
|
JCThrow Throw(JCExpression expr);
|
||||||
|
@ -3162,6 +3191,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
public void visitIf(JCIf that) { visitTree(that); }
|
public void visitIf(JCIf that) { visitTree(that); }
|
||||||
public void visitExec(JCExpressionStatement that) { visitTree(that); }
|
public void visitExec(JCExpressionStatement that) { visitTree(that); }
|
||||||
public void visitBreak(JCBreak that) { visitTree(that); }
|
public void visitBreak(JCBreak that) { visitTree(that); }
|
||||||
|
public void visitYield(JCYield that) { visitTree(that); }
|
||||||
public void visitContinue(JCContinue that) { visitTree(that); }
|
public void visitContinue(JCContinue that) { visitTree(that); }
|
||||||
public void visitReturn(JCReturn that) { visitTree(that); }
|
public void visitReturn(JCReturn that) { visitTree(that); }
|
||||||
public void visitThrow(JCThrow that) { visitTree(that); }
|
public void visitThrow(JCThrow that) { visitTree(that); }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -982,7 +982,18 @@ public class Pretty extends JCTree.Visitor {
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
try {
|
try {
|
||||||
print("break");
|
print("break");
|
||||||
if (tree.value != null) print(" " + tree.value);
|
if (tree.label != null) print(" " + tree.label);
|
||||||
|
print(";");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
try {
|
||||||
|
print("yield");
|
||||||
|
print(" ");
|
||||||
|
printExpr(tree.value);
|
||||||
print(";");
|
print(";");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UncheckedIOException(e);
|
throw new UncheckedIOException(e);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2006, 2019, 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
|
||||||
|
@ -140,8 +140,15 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
||||||
@DefinedBy(Api.COMPILER_TREE)
|
@DefinedBy(Api.COMPILER_TREE)
|
||||||
public JCTree visitBreak(BreakTree node, P p) {
|
public JCTree visitBreak(BreakTree node, P p) {
|
||||||
JCBreak t = (JCBreak) node;
|
JCBreak t = (JCBreak) node;
|
||||||
|
return M.at(t.pos).Break(t.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DefinedBy(Api.COMPILER_TREE)
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
public JCTree visitYield(YieldTree node, P p) {
|
||||||
|
JCYield t = (JCYield) node;
|
||||||
JCExpression value = copy(t.value, p);
|
JCExpression value = copy(t.value, p);
|
||||||
return M.at(t.pos).Break(value);
|
return M.at(t.pos).Yield(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DefinedBy(Api.COMPILER_TREE)
|
@DefinedBy(Api.COMPILER_TREE)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -333,12 +333,18 @@ public class TreeMaker implements JCTree.Factory {
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JCBreak Break(JCExpression label) {
|
public JCBreak Break(Name label) {
|
||||||
JCBreak tree = new JCBreak(label, null);
|
JCBreak tree = new JCBreak(label, null);
|
||||||
tree.pos = pos;
|
tree.pos = pos;
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JCYield Yield(JCExpression value) {
|
||||||
|
JCYield tree = new JCYield(value, null);
|
||||||
|
tree.pos = pos;
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
public JCContinue Continue(Name label) {
|
public JCContinue Continue(Name label) {
|
||||||
JCContinue tree = new JCContinue(label, null);
|
JCContinue tree = new JCContinue(label, null);
|
||||||
tree.pos = pos;
|
tree.pos = pos;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2019, 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
|
||||||
|
@ -219,6 +219,9 @@ public class TreeScanner extends Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
scan(tree.value);
|
scan(tree.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -258,8 +258,11 @@ public class TreeTranslator extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
if (tree.isValueBreak())
|
result = tree;
|
||||||
tree.value = translate(tree.value);
|
}
|
||||||
|
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
|
tree.value = translate(tree.value);
|
||||||
result = tree;
|
result = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -554,6 +554,13 @@ public class Log extends AbstractLog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Is an error reported at the given pos (inside the current source)?*/
|
||||||
|
public boolean hasErrorOn(DiagnosticPosition pos) {
|
||||||
|
JavaFileObject file = source != null ? source.fileObject : null;
|
||||||
|
|
||||||
|
return file != null && recorded.contains(new Pair<>(file, pos.getPreferredPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
/** Prompt user after an error.
|
/** Prompt user after an error.
|
||||||
*/
|
*/
|
||||||
public void prompt() {
|
public void prompt() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2019, 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
|
||||||
|
@ -70,6 +70,7 @@ public class Names {
|
||||||
public final Name uses;
|
public final Name uses;
|
||||||
public final Name open;
|
public final Name open;
|
||||||
public final Name with;
|
public final Name with;
|
||||||
|
public final Name yield;
|
||||||
|
|
||||||
// field and method names
|
// field and method names
|
||||||
public final Name _name;
|
public final Name _name;
|
||||||
|
@ -219,6 +220,7 @@ public class Names {
|
||||||
uses = fromString("uses");
|
uses = fromString("uses");
|
||||||
open = fromString("open");
|
open = fromString("open");
|
||||||
with = fromString("with");
|
with = fromString("with");
|
||||||
|
yield = fromString("yield");
|
||||||
|
|
||||||
// field and method names
|
// field and method names
|
||||||
_name = fromString("name");
|
_name = fromString("name");
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.var.not.allowed.array
|
// key: compiler.err.restricted.type.not.allowed.array
|
||||||
|
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018, 2019, 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.break.expr.not.immediate
|
|
||||||
// key: compiler.misc.tree.tag.doloop
|
|
||||||
// key: compiler.misc.tree.tag.foreachloop
|
|
||||||
// key: compiler.misc.tree.tag.forloop
|
|
||||||
// key: compiler.misc.tree.tag.switch
|
|
||||||
// key: compiler.misc.tree.tag.whileloop
|
|
||||||
// key: compiler.note.note
|
|
||||||
// key: compiler.err.error
|
|
||||||
// key: compiler.misc.count.error.plural
|
|
||||||
// key: compiler.note.preview.filename
|
|
||||||
// key: compiler.note.preview.recompile
|
|
||||||
// key: compiler.note.note
|
|
||||||
// options: --enable-preview -source ${jdk.version}
|
|
||||||
// run: backdoor
|
|
||||||
|
|
||||||
class BreakExprNotImmediate {
|
|
||||||
int t(int i) {
|
|
||||||
return switch (i) {
|
|
||||||
case 0:
|
|
||||||
for (; ;) {
|
|
||||||
break 1 + 1;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
for (String s : new String[0]) {
|
|
||||||
break 1 + 1;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
while (true) {
|
|
||||||
break 1 + 1;
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
do {
|
|
||||||
break 1 + 1;
|
|
||||||
} while (true);
|
|
||||||
case 4:
|
|
||||||
switch (i) {
|
|
||||||
default: break 1 + 1;
|
|
||||||
}
|
|
||||||
break 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.warn.var.not.allowed
|
// key: compiler.warn.restricted.type.not.allowed
|
||||||
// options: --release 9
|
// options: --release 9
|
||||||
|
|
||||||
class var { }
|
class var { }
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 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.warn.illegal.ref.to.restricted.type
|
||||||
|
// key: compiler.warn.restricted.type.not.allowed.preview
|
||||||
|
|
||||||
|
class IllegalRefToVarType {
|
||||||
|
yield list() { return null; }
|
||||||
|
public class yield {}
|
||||||
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.illegal.ref.to.var.type
|
// key: compiler.err.illegal.ref.to.restricted.type
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 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
|
||||||
|
@ -21,16 +21,14 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.break.ambiguous.target
|
// key: compiler.err.invalid.yield
|
||||||
// key: compiler.note.preview.filename
|
// options: --enable-preview --source 13
|
||||||
// key: compiler.note.preview.recompile
|
|
||||||
// options: --enable-preview -source ${jdk.version}
|
|
||||||
|
|
||||||
class BreakAmbiguousTarget {
|
class BreakComplexValueNoSwitchExpressions {
|
||||||
void m(int i, int j) {
|
void t() {
|
||||||
j: print(switch (i) {
|
while (true) {
|
||||||
default: break j;
|
yield(1, 2);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
void print(int i) { }
|
private void yield(int i, int j) {}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 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
|
||||||
|
@ -21,12 +21,14 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.break.complex.value.no.switch.expression
|
// key: compiler.warn.invalid.yield
|
||||||
|
// options: --source 13
|
||||||
|
|
||||||
class BreakComplexValueNoSwitchExpressions {
|
class BreakComplexValueNoSwitchExpressions {
|
||||||
void t() {
|
void t() {
|
||||||
while (true) {
|
while (true) {
|
||||||
break 1 + 1;
|
yield(1, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void yield(int i, int j) {}
|
||||||
}
|
}
|
|
@ -21,15 +21,13 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.break.missing.value
|
// key: compiler.err.no.switch.expression
|
||||||
// key: compiler.note.preview.filename
|
// options: --enable-preview --source 13
|
||||||
// key: compiler.note.preview.recompile
|
|
||||||
// options: --enable-preview -source ${jdk.version}
|
|
||||||
|
|
||||||
class BreakMissingValue {
|
class BreakComplexValueNoSwitchExpressions {
|
||||||
int t(int i) {
|
void t() {
|
||||||
return switch (i) {
|
while (true) {
|
||||||
default: break;
|
yield 1 + 1;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.no.switch.expression.qualify
|
||||||
|
// options: --enable-preview --source 13
|
||||||
|
|
||||||
|
class BreakComplexValueNoSwitchExpressions {
|
||||||
|
void t() {
|
||||||
|
while (true) {
|
||||||
|
yield(1 + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void yield(int i) {}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 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.warn.restricted.type.not.allowed.preview
|
||||||
|
|
||||||
|
class yield { }
|
|
@ -28,7 +28,7 @@
|
||||||
class SwitchExpressions {
|
class SwitchExpressions {
|
||||||
int m(int i) {
|
int m(int i) {
|
||||||
return switch (i) {
|
return switch (i) {
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,6 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.var.not.allowed
|
// key: compiler.err.restricted.type.not.allowed
|
||||||
|
|
||||||
class var { }
|
class var { }
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.var.not.allowed.array
|
// key: compiler.err.restricted.type.not.allowed.array
|
||||||
|
|
||||||
class VarNotAllowedArray {
|
class VarNotAllowedArray {
|
||||||
void test(String[] s) {
|
void test(String[] s) {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.var.not.allowed.compound
|
// key: compiler.err.restricted.type.not.allowed.compound
|
||||||
|
|
||||||
class VarNotAllowedCompound {
|
class VarNotAllowedCompound {
|
||||||
void test() {
|
void test() {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// key: compiler.err.var.not.allowed.here
|
// key: compiler.err.restricted.type.not.allowed.here
|
||||||
|
|
||||||
class VarNotAllowedField {
|
class VarNotAllowedField {
|
||||||
var s = "";
|
var s = "";
|
||||||
|
|
|
@ -48,11 +48,12 @@ public class ExpSwitchNestingTest extends JavacTemplateTestBase {
|
||||||
private static final String INT_ESWITCH_DEFAULT = "int res = switch (x) { default -> { # } };";
|
private static final String INT_ESWITCH_DEFAULT = "int res = switch (x) { default -> { # } };";
|
||||||
private static final String IF = "if (cond) { # } else throw new RuntimeException();";
|
private static final String IF = "if (cond) { # } else throw new RuntimeException();";
|
||||||
private static final String BLOCK = "{ # }";
|
private static final String BLOCK = "{ # }";
|
||||||
private static final String BREAK_Z = "break 0;";
|
private static final String YIELD_Z = "yield 0;";
|
||||||
private static final String BREAK_S = "break \"hello world\";";
|
private static final String YIELD_S = "yield \"hello world\";";
|
||||||
private static final String BREAK_INT_FN = "break () -> 0 ;";
|
private static final String YIELD_INT_FN = "yield () -> 0 ;";
|
||||||
private static final String BREAK_N = "break;";
|
private static final String BREAK_N = "break;";
|
||||||
private static final String BREAK_L = "break label;";
|
private static final String BREAK_L = "break label;";
|
||||||
|
private static final String YIELD_L = "yield label;";
|
||||||
private static final String RETURN_Z = "return 0;";
|
private static final String RETURN_Z = "return 0;";
|
||||||
private static final String RETURN_N = "return;";
|
private static final String RETURN_N = "return;";
|
||||||
private static final String RETURN_S = "return \"Hello\";";
|
private static final String RETURN_S = "return \"Hello\";";
|
||||||
|
@ -136,11 +137,11 @@ public class ExpSwitchNestingTest extends JavacTemplateTestBase {
|
||||||
assertOK(RUNNABLE, NOTHING);
|
assertOK(RUNNABLE, NOTHING);
|
||||||
assertOK(INT_FN, RETURN_Z);
|
assertOK(INT_FN, RETURN_Z);
|
||||||
assertFail("compiler.err.break.outside.switch.loop", RUNNABLE, BREAK_N);
|
assertFail("compiler.err.break.outside.switch.loop", RUNNABLE, BREAK_N);
|
||||||
assertFail("compiler.err.break.complex.value.no.switch.expression", RUNNABLE, BREAK_Z);
|
assertFail("compiler.err.no.switch.expression", RUNNABLE, YIELD_Z);
|
||||||
assertFail("compiler.err.break.complex.value.no.switch.expression", RUNNABLE, BREAK_S);
|
assertFail("compiler.err.no.switch.expression", RUNNABLE, YIELD_S);
|
||||||
assertFail("compiler.err.break.outside.switch.loop", INT_FN, BREAK_N);
|
assertFail("compiler.err.break.outside.switch.loop", INT_FN, BREAK_N);
|
||||||
assertFail("compiler.err.break.complex.value.no.switch.expression", INT_FN, BREAK_Z);
|
assertFail("compiler.err.no.switch.expression", INT_FN, YIELD_Z);
|
||||||
assertFail("compiler.err.break.complex.value.no.switch.expression", INT_FN, BREAK_S);
|
assertFail("compiler.err.no.switch.expression", INT_FN, YIELD_S);
|
||||||
assertFail("compiler.err.cont.outside.loop", RUNNABLE, CONTINUE_N);
|
assertFail("compiler.err.cont.outside.loop", RUNNABLE, CONTINUE_N);
|
||||||
assertFail("compiler.err.undef.label", RUNNABLE, BREAK_L);
|
assertFail("compiler.err.undef.label", RUNNABLE, BREAK_L);
|
||||||
assertFail("compiler.err.undef.label", RUNNABLE, CONTINUE_L);
|
assertFail("compiler.err.undef.label", RUNNABLE, CONTINUE_L);
|
||||||
|
@ -155,92 +156,94 @@ public class ExpSwitchNestingTest extends JavacTemplateTestBase {
|
||||||
|
|
||||||
public void testEswitch() {
|
public void testEswitch() {
|
||||||
//Int-valued switch expressions
|
//Int-valued switch expressions
|
||||||
assertOK(ESWITCH_Z, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z);
|
||||||
assertOK(LABEL, BLOCK, ESWITCH_Z, BREAK_Z);
|
assertOK(LABEL, BLOCK, ESWITCH_Z, YIELD_Z);
|
||||||
assertFail("compiler.err.break.missing.value", ESWITCH_Z, BREAK_N);
|
assertFail("compiler.err.break.outside.switch.expression", ESWITCH_Z, BREAK_N);
|
||||||
assertFail("compiler.err.prob.found.req", ESWITCH_Z, BREAK_S);
|
assertFail("compiler.err.prob.found.req", ESWITCH_Z, YIELD_S);
|
||||||
assertFail("compiler.err.cant.resolve.location", ESWITCH_Z, BREAK_L);
|
assertFail("compiler.err.undef.label", ESWITCH_Z, BREAK_L);
|
||||||
assertFail("compiler.err.break.outside.switch.expression", LABEL, BLOCK, ESWITCH_Z, BREAK_L);
|
assertFail("compiler.err.break.outside.switch.expression", LABEL, BLOCK, ESWITCH_Z, BREAK_L);
|
||||||
assertFail("compiler.err.undef.label", ESWITCH_Z, CONTINUE_L);
|
assertFail("compiler.err.undef.label", ESWITCH_Z, CONTINUE_L);
|
||||||
assertFail("compiler.err.cont.outside.loop", ESWITCH_Z, CONTINUE_N);
|
assertFail("compiler.err.continue.outside.switch.expression", ESWITCH_Z, CONTINUE_N);
|
||||||
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_Z, RETURN_N);
|
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_Z, RETURN_N);
|
||||||
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_Z, RETURN_Z);
|
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_Z, RETURN_Z);
|
||||||
|
|
||||||
assertOK(INT_ESWITCH_DEFAULT, BREAK_Z);
|
assertOK(INT_ESWITCH_DEFAULT, YIELD_Z);
|
||||||
assertFail("compiler.err.break.missing.value", INT_ESWITCH_DEFAULT, BREAK_N);
|
assertFail("compiler.err.break.outside.switch.expression", INT_ESWITCH_DEFAULT, BREAK_N);
|
||||||
assertFail("compiler.err.prob.found.req", INT_ESWITCH_DEFAULT, BREAK_S);
|
assertFail("compiler.err.prob.found.req", INT_ESWITCH_DEFAULT, YIELD_S);
|
||||||
assertFail("compiler.err.cant.resolve.location", INT_ESWITCH_DEFAULT, BREAK_L);
|
assertFail("compiler.err.undef.label", INT_ESWITCH_DEFAULT, BREAK_L);
|
||||||
|
|
||||||
|
|
||||||
// String-valued switch expressions
|
// String-valued switch expressions
|
||||||
assertOK(ESWITCH_S, BREAK_S);
|
assertOK(ESWITCH_S, YIELD_S);
|
||||||
assertOK(LABEL, BLOCK, ESWITCH_S, BREAK_S);
|
assertOK(LABEL, BLOCK, ESWITCH_S, YIELD_S);
|
||||||
assertFail("compiler.err.break.missing.value", ESWITCH_S, BREAK_N);
|
assertFail("compiler.err.break.outside.switch.expression", ESWITCH_S, BREAK_N);
|
||||||
assertFail("compiler.err.prob.found.req", ESWITCH_S, BREAK_Z);
|
assertFail("compiler.err.prob.found.req", ESWITCH_S, YIELD_Z);
|
||||||
assertFail("compiler.err.cant.resolve.location", ESWITCH_S, BREAK_L);
|
assertFail("compiler.err.undef.label", ESWITCH_S, BREAK_L);
|
||||||
assertFail("compiler.err.break.outside.switch.expression", LABEL, BLOCK, ESWITCH_S, BREAK_L);
|
assertFail("compiler.err.break.outside.switch.expression", LABEL, BLOCK, ESWITCH_S, BREAK_L);
|
||||||
assertFail("compiler.err.undef.label", ESWITCH_S, CONTINUE_L);
|
assertFail("compiler.err.undef.label", ESWITCH_S, CONTINUE_L);
|
||||||
assertFail("compiler.err.cont.outside.loop", ESWITCH_S, CONTINUE_N);
|
assertFail("compiler.err.continue.outside.switch.expression", ESWITCH_S, CONTINUE_N);
|
||||||
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_S, RETURN_N);
|
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_S, RETURN_N);
|
||||||
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_S, RETURN_S);
|
assertFail("compiler.err.return.outside.switch.expression", ESWITCH_S, RETURN_S);
|
||||||
// Function-valued switch expression
|
// Function-valued switch expression
|
||||||
assertOK(INT_FN_ESWITCH, BREAK_INT_FN);
|
assertOK(INT_FN_ESWITCH, YIELD_INT_FN);
|
||||||
assertFail("compiler.err.break.missing.value", INT_FN_ESWITCH, BREAK_N);
|
assertFail("compiler.err.break.outside.switch.expression", INT_FN_ESWITCH, BREAK_N);
|
||||||
assertFail("compiler.err.prob.found.req", INT_FN_ESWITCH, BREAK_Z);
|
assertFail("compiler.err.prob.found.req", INT_FN_ESWITCH, YIELD_Z);
|
||||||
assertFail("compiler.err.prob.found.req", INT_FN_ESWITCH, BREAK_S);
|
assertFail("compiler.err.prob.found.req", INT_FN_ESWITCH, YIELD_S);
|
||||||
|
|
||||||
assertFail("compiler.err.cant.resolve.location", INT_FN_ESWITCH, BREAK_L);
|
assertFail("compiler.err.undef.label", INT_FN_ESWITCH, BREAK_L);
|
||||||
assertFail("compiler.err.break.outside.switch.expression", LABEL, BLOCK, INT_FN_ESWITCH, BREAK_L);
|
assertFail("compiler.err.break.outside.switch.expression", LABEL, BLOCK, INT_FN_ESWITCH, BREAK_L);
|
||||||
assertFail("compiler.err.undef.label", INT_FN_ESWITCH, CONTINUE_L);
|
assertFail("compiler.err.undef.label", INT_FN_ESWITCH, CONTINUE_L);
|
||||||
assertFail("compiler.err.cont.outside.loop", INT_FN_ESWITCH, CONTINUE_N);
|
assertFail("compiler.err.continue.outside.switch.expression", INT_FN_ESWITCH, CONTINUE_N);
|
||||||
assertFail("compiler.err.return.outside.switch.expression", INT_FN_ESWITCH, RETURN_N);
|
assertFail("compiler.err.return.outside.switch.expression", INT_FN_ESWITCH, RETURN_N);
|
||||||
assertFail("compiler.err.return.outside.switch.expression", INT_FN_ESWITCH, RETURN_S);
|
assertFail("compiler.err.return.outside.switch.expression", INT_FN_ESWITCH, RETURN_S);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNestedInExpSwitch() {
|
public void testNestedInExpSwitch() {
|
||||||
assertOK(ESWITCH_Z, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, YIELD_Z);
|
||||||
//
|
//
|
||||||
assertOK(ESWITCH_Z, IF, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, IF, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, BLOCK, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, BLOCK, YIELD_Z);
|
||||||
//
|
//
|
||||||
assertOK(ESWITCH_Z, IF, IF, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, IF, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, IF, IF, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, IF, BLOCK, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, IF, BLOCK, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, BLOCK, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, IF, BLOCK, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, IF, BLOCK, BLOCK, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, IF, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, IF, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, IF, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, IF, BLOCK, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, BLOCK, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, BLOCK, IF, YIELD_Z);
|
||||||
assertOK(ESWITCH_Z, BLOCK, BLOCK, BLOCK, BREAK_Z);
|
assertOK(ESWITCH_Z, BLOCK, BLOCK, BLOCK, YIELD_Z);
|
||||||
//
|
//
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, SSWITCH, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, SSWITCH, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, FOR, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, FOR, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, WHILE, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, WHILE, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, DO, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, DO, YIELD_Z);
|
||||||
assertFail("compiler.err.break.complex.value.no.switch.expression", ESWITCH_Z, INT_FN, BREAK_Z);
|
assertFail("compiler.err.no.switch.expression", ESWITCH_Z, INT_FN, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, SSWITCH, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, SSWITCH, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, FOR, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, FOR, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, WHILE, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, WHILE, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, DO, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, DO, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, BLOCK, SSWITCH, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, BLOCK, SSWITCH, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, BLOCK, FOR, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, BLOCK, FOR, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, BLOCK, WHILE, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, BLOCK, WHILE, IF, YIELD_Z);
|
||||||
assertFail("compiler.err.break.expr.not.immediate", ESWITCH_Z, BLOCK, DO, IF, BREAK_Z);
|
assertOK(ESWITCH_Z, YIELD_Z, BLOCK, DO, IF, YIELD_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBreakExpressionLabelDisambiguation() {
|
public void testBreakExpressionLabelDisambiguation() {
|
||||||
assertOK(DEF_LABEL_VAR, ESWITCH_Z, BREAK_L);
|
assertOK(DEF_LABEL_VAR, ESWITCH_Z, YIELD_L);
|
||||||
assertFail("compiler.err.break.ambiguous.target", LABEL, FOR, BLOCK, DEF_LABEL_VAR, ESWITCH_Z, BREAK_L);
|
assertFail("compiler.err.undef.label", DEF_LABEL_VAR, ESWITCH_Z, BREAK_L);
|
||||||
assertFail("compiler.err.break.ambiguous.target", DEF_LABEL_VAR, ESWITCH_Z, LABEL, FOR, BREAK_L); //label break
|
assertFail("compiler.err.break.outside.switch.expression", LABEL, FOR, BLOCK, DEF_LABEL_VAR, ESWITCH_Z, BREAK_L);
|
||||||
assertFail("compiler.err.break.ambiguous.target", DEF_LABEL_VAR, LABEL, BLOCK, ESWITCH_Z, BREAK_L); //expression break
|
assertOK(DEF_LABEL_VAR, ESWITCH_Z, YIELD_Z, LABEL, FOR, BREAK_L); //label break
|
||||||
|
assertFail("compiler.err.break.outside.switch.expression", DEF_LABEL_VAR, LABEL, BLOCK, ESWITCH_Z, BREAK_L);
|
||||||
|
assertOK(DEF_LABEL_VAR, LABEL, BLOCK, ESWITCH_Z, YIELD_L); //expression break
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFunReturningSwitchExp() {
|
public void testFunReturningSwitchExp() {
|
||||||
assertOK(INT_FN_ESWITCH, BREAK_INT_FN);
|
assertOK(INT_FN_ESWITCH, YIELD_INT_FN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testContinueLoops() {
|
public void testContinueLoops() {
|
||||||
|
|
|
@ -160,6 +160,9 @@ public class Deduplication {
|
||||||
group((Consumer<Integer>) x -> Deduplication.this.f());
|
group((Consumer<Integer>) x -> Deduplication.this.f());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group((Function<Integer, Integer>) x -> switch (x) { default: yield x; },
|
||||||
|
(Function<Integer, Integer>) x -> switch (x) { default: yield x; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void f() {}
|
void f() {}
|
||||||
|
|
|
@ -84,6 +84,7 @@ public class DeduplicationTest {
|
||||||
Listener diagnosticListener = new Listener();
|
Listener diagnosticListener = new Listener();
|
||||||
Path testSrc = Paths.get(System.getProperty("test.src"));
|
Path testSrc = Paths.get(System.getProperty("test.src"));
|
||||||
Path file = testSrc.resolve("Deduplication.java");
|
Path file = testSrc.resolve("Deduplication.java");
|
||||||
|
String sourceVersion = Integer.toString(Runtime.version().feature());
|
||||||
JavacTask task =
|
JavacTask task =
|
||||||
javacTool.getTask(
|
javacTool.getTask(
|
||||||
null,
|
null,
|
||||||
|
@ -93,7 +94,8 @@ public class DeduplicationTest {
|
||||||
"-d",
|
"-d",
|
||||||
".",
|
".",
|
||||||
"-XDdebug.dumpLambdaToMethodDeduplication",
|
"-XDdebug.dumpLambdaToMethodDeduplication",
|
||||||
"-XDdebug.dumpLambdaToMethodStats"),
|
"-XDdebug.dumpLambdaToMethodStats",
|
||||||
|
"--enable-preview", "-source", sourceVersion),
|
||||||
null,
|
null,
|
||||||
fileManager.getJavaFileObjects(file));
|
fileManager.getJavaFileObjects(file));
|
||||||
Map<JCLambda, JCLambda> dedupedLambdas = new LinkedHashMap<>();
|
Map<JCLambda, JCLambda> dedupedLambdas = new LinkedHashMap<>();
|
||||||
|
@ -192,6 +194,9 @@ public class DeduplicationTest {
|
||||||
(JCLambda) d.getDiagnosticPosition().getTree(),
|
(JCLambda) d.getDiagnosticPosition().getTree(),
|
||||||
(MethodSymbol) d.getArgs()[0]);
|
(MethodSymbol) d.getArgs()[0]);
|
||||||
break;
|
break;
|
||||||
|
case "compiler.note.preview.filename":
|
||||||
|
case "compiler.note.preview.recompile":
|
||||||
|
break; //ignore
|
||||||
default:
|
default:
|
||||||
unexpected.add(diagnostic);
|
unexpected.add(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -782,6 +782,11 @@ public class DPrinter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitBreak(JCBreak tree) {
|
public void visitBreak(JCBreak tree) {
|
||||||
|
printName("label", tree.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitYield(JCYield tree) {
|
||||||
printTree("value", tree.value);
|
printTree("value", tree.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
ParserTest.java:14:18: compiler.err.var.not.allowed
|
ParserTest.java:14:18: compiler.err.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:16:22: compiler.err.var.not.allowed
|
ParserTest.java:16:22: compiler.err.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:20:19: compiler.err.var.not.allowed
|
ParserTest.java:20:19: compiler.err.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:24:14: compiler.err.var.not.allowed
|
ParserTest.java:24:14: compiler.err.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:28:20: compiler.err.var.not.allowed
|
ParserTest.java:28:20: compiler.err.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:36:27: compiler.err.var.not.allowed
|
ParserTest.java:36:27: compiler.err.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:38:5: compiler.err.var.not.allowed.here
|
ParserTest.java:38:5: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:41:15: compiler.err.var.not.allowed.array
|
ParserTest.java:41:15: compiler.err.restricted.type.not.allowed.array: var
|
||||||
ParserTest.java:42:13: compiler.err.var.not.allowed.array
|
ParserTest.java:42:13: compiler.err.restricted.type.not.allowed.array: var
|
||||||
ParserTest.java:43:17: compiler.err.var.not.allowed.array
|
ParserTest.java:43:17: compiler.err.restricted.type.not.allowed.array: var
|
||||||
ParserTest.java:44:13: compiler.err.var.not.allowed.array
|
ParserTest.java:44:13: compiler.err.restricted.type.not.allowed.array: var
|
||||||
ParserTest.java:45:15: compiler.err.var.not.allowed.array
|
ParserTest.java:45:15: compiler.err.restricted.type.not.allowed.array: var
|
||||||
ParserTest.java:46:13: compiler.err.var.not.allowed.array
|
ParserTest.java:46:13: compiler.err.restricted.type.not.allowed.array: var
|
||||||
ParserTest.java:49:24: compiler.err.var.not.allowed.compound
|
ParserTest.java:49:24: compiler.err.restricted.type.not.allowed.compound: var
|
||||||
ParserTest.java:54:5: compiler.err.var.not.allowed.here
|
ParserTest.java:54:5: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:58:16: compiler.err.var.not.allowed.here
|
ParserTest.java:58:16: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:59:14: compiler.err.var.not.allowed.here
|
ParserTest.java:59:14: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:60:24: compiler.err.var.not.allowed.here
|
ParserTest.java:60:24: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:61:22: compiler.err.var.not.allowed.here
|
ParserTest.java:61:22: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:63:22: compiler.err.var.not.allowed.here
|
ParserTest.java:63:22: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:64:18: compiler.err.var.not.allowed.here
|
ParserTest.java:64:18: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:68:35: compiler.err.var.not.allowed.here
|
ParserTest.java:68:35: compiler.err.restricted.type.not.allowed.here: var
|
||||||
ParserTest.java:69:22: compiler.err.var.not.allowed.here
|
ParserTest.java:69:22: compiler.err.restricted.type.not.allowed.here: var
|
||||||
23 errors
|
23 errors
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
ParserTest.java:14:18: compiler.warn.var.not.allowed
|
ParserTest.java:14:18: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:16:22: compiler.warn.var.not.allowed
|
ParserTest.java:16:22: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:20:19: compiler.warn.var.not.allowed
|
ParserTest.java:20:19: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:24:14: compiler.warn.var.not.allowed
|
ParserTest.java:24:14: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:28:20: compiler.warn.var.not.allowed
|
ParserTest.java:28:20: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:36:27: compiler.warn.var.not.allowed
|
ParserTest.java:36:27: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:38:5: compiler.warn.var.not.allowed
|
ParserTest.java:38:5: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:41:15: compiler.warn.var.not.allowed
|
ParserTest.java:41:15: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:42:13: compiler.warn.var.not.allowed
|
ParserTest.java:42:13: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:43:17: compiler.warn.var.not.allowed
|
ParserTest.java:43:17: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:44:13: compiler.warn.var.not.allowed
|
ParserTest.java:44:13: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:45:15: compiler.warn.var.not.allowed
|
ParserTest.java:45:15: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:46:13: compiler.warn.var.not.allowed
|
ParserTest.java:46:13: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:47:23: compiler.warn.var.not.allowed
|
ParserTest.java:47:23: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:48:13: compiler.warn.var.not.allowed
|
ParserTest.java:48:13: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:49:13: compiler.warn.var.not.allowed
|
ParserTest.java:49:13: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:50:23: compiler.warn.var.not.allowed
|
ParserTest.java:50:23: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:51:23: compiler.warn.var.not.allowed
|
ParserTest.java:51:23: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:54:5: compiler.warn.var.not.allowed
|
ParserTest.java:54:5: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:58:16: compiler.warn.var.not.allowed
|
ParserTest.java:58:16: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:59:14: compiler.warn.var.not.allowed
|
ParserTest.java:59:14: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:60:24: compiler.warn.var.not.allowed
|
ParserTest.java:60:24: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:61:22: compiler.warn.var.not.allowed
|
ParserTest.java:61:22: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:63:22: compiler.warn.var.not.allowed
|
ParserTest.java:63:22: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:63:40: compiler.warn.var.not.allowed
|
ParserTest.java:63:40: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:64:18: compiler.warn.var.not.allowed
|
ParserTest.java:64:18: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:68:35: compiler.warn.var.not.allowed
|
ParserTest.java:68:35: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:69:22: compiler.warn.var.not.allowed
|
ParserTest.java:69:22: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:73:24: compiler.warn.var.not.allowed
|
ParserTest.java:73:24: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
ParserTest.java:74:18: compiler.warn.var.not.allowed
|
ParserTest.java:74:18: compiler.warn.restricted.type.not.allowed: var, 10
|
||||||
30 warnings
|
30 warnings
|
|
@ -1,3 +1,3 @@
|
||||||
BadTypeReference.java:14:9: compiler.err.illegal.ref.to.var.type
|
BadTypeReference.java:14:9: compiler.err.illegal.ref.to.restricted.type: var
|
||||||
BadTypeReference.java:15:21: compiler.err.illegal.ref.to.var.type
|
BadTypeReference.java:15:21: compiler.err.illegal.ref.to.restricted.type: var
|
||||||
2 errors
|
2 errors
|
||||||
|
|
|
@ -1083,12 +1083,12 @@ public class JavacParserTest extends TestCase {
|
||||||
" }" +
|
" }" +
|
||||||
" int j = switch (i) {" +
|
" int j = switch (i) {" +
|
||||||
" case 0 -> i + 1;" +
|
" case 0 -> i + 1;" +
|
||||||
" case 1 -> { break i + 1; }" +
|
" case 1 -> { yield i + 1; }" +
|
||||||
" default -> throw new RuntimeException();" +
|
" default -> throw new RuntimeException();" +
|
||||||
" };" +
|
" };" +
|
||||||
" int k = switch (i) {" +
|
" int k = switch (i) {" +
|
||||||
" case 0: break i + 1;" +
|
" case 0: yield i + 1;" +
|
||||||
" case 1: { break i + 1; }" +
|
" case 1: { yield i + 1; }" +
|
||||||
" default: throw new RuntimeException();" +
|
" default: throw new RuntimeException();" +
|
||||||
" };" +
|
" };" +
|
||||||
" }" +
|
" }" +
|
||||||
|
@ -1120,7 +1120,7 @@ public class JavacParserTest extends TestCase {
|
||||||
List<String> expectedSpans = List.of(
|
List<String> expectedSpans = List.of(
|
||||||
"i++;", "{ i++; }", "throw new RuntimeException();", "if (true) ;", "i++;",
|
"i++;", "{ i++; }", "throw new RuntimeException();", "if (true) ;", "i++;",
|
||||||
"<null>", "<null>", "<null>", "<null>", "<null>",
|
"<null>", "<null>", "<null>", "<null>", "<null>",
|
||||||
"i + 1"/*TODO semicolon?*/, "{ break i + 1; }", "throw new RuntimeException();",
|
"i + 1"/*TODO semicolon?*/, "{ yield i + 1; }", "throw new RuntimeException();",
|
||||||
"<null>", "<null>", "<null>");
|
"<null>", "<null>", "<null>");
|
||||||
assertEquals("the error spans are not correct; actual:" + spans, expectedSpans, spans);
|
assertEquals("the error spans are not correct; actual:" + spans, expectedSpans, spans);
|
||||||
String toString = normalize(cut.toString());
|
String toString = normalize(cut.toString());
|
||||||
|
@ -1162,19 +1162,19 @@ public class JavacParserTest extends TestCase {
|
||||||
" \n" +
|
" \n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" int j = switch (i) {\n" +
|
" int j = switch (i) {\n" +
|
||||||
" case 0 -> break i + 1;\n" +
|
" case 0 -> yield i + 1;\n" +
|
||||||
" case 1 -> {\n" +
|
" case 1 -> {\n" +
|
||||||
" break i + 1;\n" +
|
" yield i + 1;\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" default -> throw new RuntimeException();\n" +
|
" default -> throw new RuntimeException();\n" +
|
||||||
" };\n" +
|
" };\n" +
|
||||||
" int k = switch (i) {\n" +
|
" int k = switch (i) {\n" +
|
||||||
" case 0:\n" +
|
" case 0:\n" +
|
||||||
" break i + 1;\n" +
|
" yield i + 1;\n" +
|
||||||
" \n" +
|
" \n" +
|
||||||
" case 1:\n" +
|
" case 1:\n" +
|
||||||
" {\n" +
|
" {\n" +
|
||||||
" break i + 1;\n" +
|
" yield i + 1;\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" \n" +
|
" \n" +
|
||||||
" default:\n" +
|
" default:\n" +
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class BreakTest {
|
||||||
" int t2(Integer i) {" +
|
" int t2(Integer i) {" +
|
||||||
" return switch (i) {" +
|
" return switch (i) {" +
|
||||||
" case null: break LABEL;" +
|
" case null: break LABEL;" +
|
||||||
" default: break 2;" +
|
" default: yield 2;" +
|
||||||
" }" +
|
" }" +
|
||||||
" }" +
|
" }" +
|
||||||
"}";
|
"}";
|
||||||
|
@ -79,7 +79,7 @@ public class BreakTest {
|
||||||
}
|
}
|
||||||
}.scan(ct.parse(), null);
|
}.scan(ct.parse(), null);
|
||||||
|
|
||||||
List<String> expected = Arrays.asList("LABEL", null, "LABEL", null);
|
List<String> expected = Arrays.asList("LABEL", null, "LABEL");
|
||||||
|
|
||||||
if (!expected.equals(labels)) {
|
if (!expected.equals(labels)) {
|
||||||
throw new AssertionError("Unexpected labels found: " + labels);
|
throw new AssertionError("Unexpected labels found: " + labels);
|
||||||
|
|
|
@ -37,8 +37,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t1 = (b && switch(a) {
|
boolean t1 = (b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || true;
|
case 0: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t1) {
|
if (!t1) {
|
||||||
|
@ -50,8 +50,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t1 = (b && switch(a) {
|
boolean t1 = (b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || isTrue();
|
case 0: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t1) {
|
if (!t1) {
|
||||||
|
@ -63,8 +63,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t1a = (b && switch(a) {
|
boolean t1a = (b && switch(a) {
|
||||||
case 0: break (x = 1) == 1;
|
case 0: yield (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t1a) {
|
if (!t1a) {
|
||||||
|
@ -76,8 +76,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t1b = (switch(a) {
|
boolean t1b = (switch(a) {
|
||||||
case 0: break (x = 1) == 1;
|
case 0: yield (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t1b) {
|
if (!t1b) {
|
||||||
|
@ -89,8 +89,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t2 = !(b && switch(a) {
|
boolean t2 = !(b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || true;
|
case 0: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 1;
|
}) || x == 1;
|
||||||
|
|
||||||
if (!t2) {
|
if (!t2) {
|
||||||
|
@ -102,8 +102,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t2 = !(b && switch(a) {
|
boolean t2 = !(b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || isTrue();
|
case 0: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 1;
|
}) || x == 1;
|
||||||
|
|
||||||
if (!t2) {
|
if (!t2) {
|
||||||
|
@ -115,8 +115,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t3 = !(switch(a) {
|
boolean t3 = !(switch(a) {
|
||||||
case 0: break (x = 1) == 1 || true;
|
case 0: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 2;
|
}) || x == 2;
|
||||||
|
|
||||||
if (t3) {
|
if (t3) {
|
||||||
|
@ -128,8 +128,8 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t3 = !(switch(a) {
|
boolean t3 = !(switch(a) {
|
||||||
case 0: break (x = 1) == 1 || isTrue();
|
case 0: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 2;
|
}) || x == 2;
|
||||||
|
|
||||||
if (t3) {
|
if (t3) {
|
||||||
|
@ -141,7 +141,7 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t4 = (b && switch(a) {
|
boolean t4 = (b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || true;
|
case 0: yield (x = 1) == 1 || true;
|
||||||
default: throw new IllegalStateException();
|
default: throw new IllegalStateException();
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ public class DefiniteAssignment1 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
boolean t4 = (b && switch(a) {
|
boolean t4 = (b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || isTrue();
|
case 0: yield (x = 1) == 1 || isTrue();
|
||||||
default: throw new IllegalStateException();
|
default: throw new IllegalStateException();
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
|
@ -170,8 +170,8 @@ public class DefiniteAssignment1 {
|
||||||
String s = "a";
|
String s = "a";
|
||||||
|
|
||||||
boolean t5 = (switch(s) {
|
boolean t5 = (switch(s) {
|
||||||
case "a": break (x = 1) == 1 || true;
|
case "a": yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t5) {
|
if (!t5) {
|
||||||
|
@ -185,8 +185,8 @@ public class DefiniteAssignment1 {
|
||||||
String s = "a";
|
String s = "a";
|
||||||
|
|
||||||
boolean t5 = (switch(s) {
|
boolean t5 = (switch(s) {
|
||||||
case "a": break (x = 1) == 1 || isTrue();
|
case "a": yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t5) {
|
if (!t5) {
|
||||||
|
@ -199,8 +199,8 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.B;
|
E e = E.B;
|
||||||
|
|
||||||
boolean t6 = (switch(e) {
|
boolean t6 = (switch(e) {
|
||||||
case B: break (x = 1) == 1 || true;
|
case B: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t6) {
|
if (!t6) {
|
||||||
|
@ -213,8 +213,8 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.B;
|
E e = E.B;
|
||||||
|
|
||||||
boolean t6 = (switch(e) {
|
boolean t6 = (switch(e) {
|
||||||
case B: break (x = 1) == 1 || isTrue();
|
case B: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t6) {
|
if (!t6) {
|
||||||
|
@ -251,9 +251,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.B;
|
E e = E.B;
|
||||||
|
|
||||||
boolean t8 = (switch(e) {
|
boolean t8 = (switch(e) {
|
||||||
case A: x = 1; break true;
|
case A: x = 1; yield true;
|
||||||
case B: break (x = 1) == 1 || true;
|
case B: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t8) {
|
if (!t8) {
|
||||||
|
@ -266,9 +266,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.B;
|
E e = E.B;
|
||||||
|
|
||||||
boolean t8 = (switch(e) {
|
boolean t8 = (switch(e) {
|
||||||
case A: x = 1; break isTrue();
|
case A: x = 1; yield isTrue();
|
||||||
case B: break (x = 1) == 1 || isTrue();
|
case B: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t8) {
|
if (!t8) {
|
||||||
|
@ -281,9 +281,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.A;
|
E e = E.A;
|
||||||
|
|
||||||
boolean t9 = (switch(e) {
|
boolean t9 = (switch(e) {
|
||||||
case A: x = 1; break true;
|
case A: x = 1; yield true;
|
||||||
case B: break (x = 1) == 1 || true;
|
case B: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t9) {
|
if (!t9) {
|
||||||
|
@ -296,9 +296,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.A;
|
E e = E.A;
|
||||||
|
|
||||||
boolean t9 = (switch(e) {
|
boolean t9 = (switch(e) {
|
||||||
case A: x = 1; break isTrue();
|
case A: x = 1; yield isTrue();
|
||||||
case B: break (x = 1) == 1 || isTrue();
|
case B: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!t9) {
|
if (!t9) {
|
||||||
|
@ -311,9 +311,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.C;
|
E e = E.C;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A: x = 1; break true;
|
case A: x = 1; yield true;
|
||||||
case B: break (x = 1) == 1 || true;
|
case B: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (tA) {
|
if (tA) {
|
||||||
|
@ -326,9 +326,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.C;
|
E e = E.C;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A: x = 1; break isTrue();
|
case A: x = 1; yield isTrue();
|
||||||
case B: break (x = 1) == 1 || isTrue();
|
case B: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (tA) {
|
if (tA) {
|
||||||
|
@ -341,9 +341,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.C;
|
E e = E.C;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A: x = 1; break true;
|
case A: x = 1; yield true;
|
||||||
case B: break (x = 2) == 2 || true;
|
case B: yield (x = 2) == 2 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || (x = 3) == 3; //x is definitelly unassigned here
|
}) || (x = 3) == 3; //x is definitelly unassigned here
|
||||||
|
|
||||||
if (x != 3) {
|
if (x != 3) {
|
||||||
|
@ -356,9 +356,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.A;
|
E e = E.A;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A: break isTrue() && (x = 1) == 1;
|
case A: yield isTrue() && (x = 1) == 1;
|
||||||
case B: break (x = 1) == 1 || isTrue();
|
case B: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!tA) {
|
if (!tA) {
|
||||||
|
@ -371,9 +371,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.A;
|
E e = E.A;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A: break isTrue() && e != E.C ? (x = 1) == 1 && e != E.B : false;
|
case A: yield isTrue() && e != E.C ? (x = 1) == 1 && e != E.B : false;
|
||||||
case B: break (x = 1) == 1 || true;
|
case B: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!tA) {
|
if (!tA) {
|
||||||
|
@ -386,9 +386,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.A;
|
E e = E.A;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A: break isTrue() && e != E.C ? (x = 1) == 1 && e != E.B : false;
|
case A: yield isTrue() && e != E.C ? (x = 1) == 1 && e != E.B : false;
|
||||||
case B: break (x = 1) == 1 || isTrue();
|
case B: yield (x = 1) == 1 || isTrue();
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!tA) {
|
if (!tA) {
|
||||||
|
@ -416,9 +416,9 @@ public class DefiniteAssignment1 {
|
||||||
E e = E.A;
|
E e = E.A;
|
||||||
|
|
||||||
boolean tA = (switch(e) {
|
boolean tA = (switch(e) {
|
||||||
case A -> { x = 1; break true; }
|
case A -> { x = 1; yield true; }
|
||||||
case B -> { x = 1; break true; }
|
case B -> { x = 1; yield true; }
|
||||||
case C -> { x = 1; break true; }
|
case C -> { x = 1; yield true; }
|
||||||
}) && x == 1; //x is definitelly assigned here
|
}) && x == 1; //x is definitelly assigned here
|
||||||
|
|
||||||
if (!tA) {
|
if (!tA) {
|
||||||
|
|
|
@ -15,8 +15,8 @@ public class DefiniteAssignment2 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
t = (b && switch(a) {
|
t = (b && switch(a) {
|
||||||
case 0: break (x = 1) == 1 || true;
|
case 0: yield (x = 1) == 1 || true;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 1;
|
}) || x == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ public class DefiniteAssignment2 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
t = (switch(a) {
|
t = (switch(a) {
|
||||||
case 0: break (x = 1) == 1;
|
case 0: yield (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 1;
|
}) || x == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ public class DefiniteAssignment2 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
t = (switch(a) {
|
t = (switch(a) {
|
||||||
case 0: x = 1; break true;
|
case 0: x = 1; yield true;
|
||||||
case 1: break (x = 1) == 1;
|
case 1: yield (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) || x == 1;
|
}) || x == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ public class DefiniteAssignment2 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
t = (switch(a) {
|
t = (switch(a) {
|
||||||
case 0: break true;
|
case 0: yield true;
|
||||||
case 1: break (x = 1) == 1;
|
case 1: yield (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1;
|
}) && x == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +53,9 @@ public class DefiniteAssignment2 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
t = (switch(a) {
|
t = (switch(a) {
|
||||||
case 0: break false;
|
case 0: yield false;
|
||||||
case 1: break isTrue() || (x = 1) == 1;
|
case 1: yield isTrue() || (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1;
|
}) && x == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ public class DefiniteAssignment2 {
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
t = (switch(a) {
|
t = (switch(a) {
|
||||||
case 0: break false;
|
case 0: yield false;
|
||||||
case 1: break isTrue() ? true : (x = 1) == 1;
|
case 1: yield isTrue() ? true : (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && x == 1;
|
}) && x == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ public class DefiniteAssignment2 {
|
||||||
final int x;
|
final int x;
|
||||||
|
|
||||||
t = (switch(a) {
|
t = (switch(a) {
|
||||||
case 0: break false;
|
case 0: yield false;
|
||||||
case 1: break isTrue() ? true : (x = 1) == 1;
|
case 1: yield isTrue() ? true : (x = 1) == 1;
|
||||||
default: break false;
|
default: yield false;
|
||||||
}) && (x = 1) == 1;
|
}) && (x = 1) == 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,15 @@ public class ExpressionSwitch {
|
||||||
private String print(T t) {
|
private String print(T t) {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A -> "A";
|
case A -> "A";
|
||||||
case B -> { break "B"; }
|
case B -> { yield "B"; }
|
||||||
default -> { break "other"; }
|
default -> { yield "other"; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private String exhaustive1(T t) {
|
private String exhaustive1(T t) {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A -> "A";
|
case A -> "A";
|
||||||
case B -> { break "B"; }
|
case B -> { yield "B"; }
|
||||||
case C -> "C";
|
case C -> "C";
|
||||||
case D -> "D";
|
case D -> "D";
|
||||||
};
|
};
|
||||||
|
@ -64,25 +64,25 @@ public class ExpressionSwitch {
|
||||||
|
|
||||||
private String scopesIsolated(T t) {
|
private String scopesIsolated(T t) {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A -> { String res = "A"; break res;}
|
case A -> { String res = "A"; yield res;}
|
||||||
case B -> { String res = "B"; break res;}
|
case B -> { String res = "B"; yield res;}
|
||||||
default -> { String res = "default"; break res;}
|
default -> { String res = "default"; yield res;}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<String> lambdas1(T t) {
|
private Supplier<String> lambdas1(T t) {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A -> () -> "A";
|
case A -> () -> "A";
|
||||||
case B -> { break () -> "B"; }
|
case B -> { yield () -> "B"; }
|
||||||
default -> () -> "default";
|
default -> () -> "default";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<String> lambdas2(T t) {
|
private Supplier<String> lambdas2(T t) {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A: break () -> "A";
|
case A: yield () -> "A";
|
||||||
case B: { break () -> "B"; }
|
case B: { yield () -> "B"; }
|
||||||
default: break () -> "default";
|
default: yield () -> "default";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,16 +91,16 @@ public class ExpressionSwitch {
|
||||||
? -2
|
? -2
|
||||||
: switch (s) {
|
: switch (s) {
|
||||||
case "A", "B" -> 0;
|
case "A", "B" -> 0;
|
||||||
case "C" -> { break 1; }
|
case "C" -> { yield 1; }
|
||||||
default -> -1;
|
default -> -1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private int convert2(String s) {
|
private int convert2(String s) {
|
||||||
return switch (s) {
|
return switch (s) {
|
||||||
case "A", "B": break 0;
|
case "A", "B": yield 0;
|
||||||
case "C": break 1;
|
case "C": yield 1;
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ public class ExpressionSwitch {
|
||||||
default: break STOP;
|
default: break STOP;
|
||||||
}
|
}
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
default: break good;
|
default: yield good;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,11 +58,11 @@ public class ExpressionSwitchBreaks1 {
|
||||||
case 0:
|
case 0:
|
||||||
return switch (j) {
|
return switch (j) {
|
||||||
case 0:
|
case 0:
|
||||||
if (true) break "0-0";
|
if (true) yield "0-0";
|
||||||
case 1:
|
case 1:
|
||||||
break "0-1";
|
yield "0-1";
|
||||||
default:
|
default:
|
||||||
break "0-X";
|
yield "0-X";
|
||||||
};
|
};
|
||||||
default: return "X";
|
default: return "X";
|
||||||
}
|
}
|
||||||
|
@ -90,9 +90,9 @@ public class ExpressionSwitchBreaks1 {
|
||||||
r = "0-X";
|
r = "0-X";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break r;
|
yield r;
|
||||||
case 1:
|
case 1:
|
||||||
break "1";
|
yield "1";
|
||||||
case 2:
|
case 2:
|
||||||
LOP: while (j-- > 0) {
|
LOP: while (j-- > 0) {
|
||||||
if (k == 5) {
|
if (k == 5) {
|
||||||
|
@ -102,9 +102,9 @@ public class ExpressionSwitchBreaks1 {
|
||||||
break LOP;
|
break LOP;
|
||||||
}
|
}
|
||||||
Supplier<String> getter = () -> { return "2-X-5"; };
|
Supplier<String> getter = () -> { return "2-X-5"; };
|
||||||
break getter.get();
|
yield getter.get();
|
||||||
default:
|
default:
|
||||||
break "X";
|
yield "X";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class ExpressionSwitchBreaks2 {
|
||||||
case 0:
|
case 0:
|
||||||
return switch (j) {
|
return switch (j) {
|
||||||
case 0:
|
case 0:
|
||||||
break "0-0";
|
yield "0-0";
|
||||||
case 1:
|
case 1:
|
||||||
break ; //error: missing value
|
break ; //error: missing value
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -20,9 +20,9 @@ public class ExpressionSwitchBreaks2 {
|
||||||
case 3: {
|
case 3: {
|
||||||
int x = -1;
|
int x = -1;
|
||||||
x: switch (i + j) {
|
x: switch (i + j) {
|
||||||
case 0: break x; //error: cannot disambiguate, wrong type as well
|
case 0: break x;
|
||||||
}
|
}
|
||||||
break "X";
|
yield "X";
|
||||||
}
|
}
|
||||||
case 4: return "X"; //error: no returns from inside of the switch expression
|
case 4: return "X"; //error: no returns from inside of the switch expression
|
||||||
case 5: continue; //error: no continue out of the switch expression
|
case 5: continue; //error: no continue out of the switch expression
|
||||||
|
@ -31,17 +31,17 @@ public class ExpressionSwitchBreaks2 {
|
||||||
default: {
|
default: {
|
||||||
String x = "X";
|
String x = "X";
|
||||||
x: switch (i + j) {
|
x: switch (i + j) {
|
||||||
case 0: break ""; //error: cannot break from switch expression that is not immediatelly enclosing
|
case 0: yield ""; //error: cannot yield from switch expression that is not immediatelly enclosing
|
||||||
}
|
}
|
||||||
break "X";
|
yield "X";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case 1:
|
case 1:
|
||||||
break "1" + undef; //error: complex value and no switch expression
|
yield "1" + undef; //error: complex value and no switch expression
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
j: print(switch (i) {
|
j: print(switch (i) {
|
||||||
default: break j; //error: "j" is ambiguous (expression/label)
|
default: break j;
|
||||||
}, 0);
|
}, 0);
|
||||||
j2: print(switch (i) {
|
j2: print(switch (i) {
|
||||||
default: break j2;
|
default: break j2;
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
ExpressionSwitchBreaks2.java:17:25: compiler.err.break.missing.value
|
|
||||||
ExpressionSwitchBreaks2.java:19:25: compiler.err.break.outside.switch.expression
|
ExpressionSwitchBreaks2.java:19:25: compiler.err.break.outside.switch.expression
|
||||||
ExpressionSwitchBreaks2.java:23:37: compiler.err.break.ambiguous.target: x
|
|
||||||
ExpressionSwitchBreaks2.java:27:29: compiler.err.return.outside.switch.expression
|
ExpressionSwitchBreaks2.java:27:29: compiler.err.return.outside.switch.expression
|
||||||
ExpressionSwitchBreaks2.java:28:29: compiler.err.continue.outside.switch.expression
|
ExpressionSwitchBreaks2.java:28:29: compiler.err.continue.outside.switch.expression
|
||||||
ExpressionSwitchBreaks2.java:29:29: compiler.err.continue.outside.switch.expression
|
ExpressionSwitchBreaks2.java:29:29: compiler.err.continue.outside.switch.expression
|
||||||
ExpressionSwitchBreaks2.java:30:29: compiler.err.undef.label: UNKNOWN
|
ExpressionSwitchBreaks2.java:30:29: compiler.err.undef.label: UNKNOWN
|
||||||
ExpressionSwitchBreaks2.java:34:37: compiler.err.break.expr.not.immediate: compiler.misc.tree.tag.switch
|
ExpressionSwitchBreaks2.java:40:17: compiler.err.no.switch.expression
|
||||||
ExpressionSwitchBreaks2.java:40:17: compiler.err.break.complex.value.no.switch.expression
|
|
||||||
ExpressionSwitchBreaks2.java:40:29: compiler.err.cant.resolve.location: kindname.variable, undef, , , (compiler.misc.location: kindname.class, ExpressionSwitchBreaks2, null)
|
ExpressionSwitchBreaks2.java:40:29: compiler.err.cant.resolve.location: kindname.variable, undef, , , (compiler.misc.location: kindname.class, ExpressionSwitchBreaks2, null)
|
||||||
ExpressionSwitchBreaks2.java:44:22: compiler.err.break.ambiguous.target: j
|
ExpressionSwitchBreaks2.java:44:22: compiler.err.break.outside.switch.expression
|
||||||
ExpressionSwitchBreaks2.java:47:22: compiler.err.break.outside.switch.expression
|
ExpressionSwitchBreaks2.java:47:22: compiler.err.break.outside.switch.expression
|
||||||
- compiler.note.preview.filename: ExpressionSwitchBreaks2.java
|
- compiler.note.preview.filename: ExpressionSwitchBreaks2.java
|
||||||
- compiler.note.preview.recompile
|
- compiler.note.preview.recompile
|
||||||
12 errors
|
9 errors
|
||||||
|
|
|
@ -34,47 +34,49 @@ public class ExpressionSwitchBugs {
|
||||||
new ExpressionSwitchBugs().testNested();
|
new ExpressionSwitchBugs().testNested();
|
||||||
new ExpressionSwitchBugs().testAnonymousClasses();
|
new ExpressionSwitchBugs().testAnonymousClasses();
|
||||||
new ExpressionSwitchBugs().testFields();
|
new ExpressionSwitchBugs().testFields();
|
||||||
|
check(3, new C(-1, 3).test(false));
|
||||||
|
check(3, new C(3, -1).test(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testNested() {
|
private void testNested() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
check(42, id(switch (42) {
|
check(42, id(switch (42) {
|
||||||
default: i++; break 42;
|
default: i++; yield 42;
|
||||||
}));
|
}));
|
||||||
i = 0;
|
i = 0;
|
||||||
check(43, id(switch (42) {
|
check(43, id(switch (42) {
|
||||||
case 42: while (i == 0) {
|
case 42: while (i == 0) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
break 42 + i;
|
yield 42 + i;
|
||||||
default: i++; break 42;
|
default: i++; yield 42;
|
||||||
}));
|
}));
|
||||||
i = 0;
|
i = 0;
|
||||||
check(42, id(switch (42) {
|
check(42, id(switch (42) {
|
||||||
case 42: if (i == 0) {
|
case 42: if (i == 0) {
|
||||||
break 42;
|
yield 42;
|
||||||
}
|
}
|
||||||
default: i++; break 43;
|
default: i++; yield 43;
|
||||||
}));
|
}));
|
||||||
i = 0;
|
i = 0;
|
||||||
check(42, id(switch (42) {
|
check(42, id(switch (42) {
|
||||||
case 42: if (i == 0) {
|
case 42: if (i == 0) {
|
||||||
break 41 + switch (0) {
|
yield 41 + switch (0) {
|
||||||
case 0 -> 1;
|
case 0 -> 1;
|
||||||
default -> -1;
|
default -> -1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
default: i++; break 43;
|
default: i++; yield 43;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testAnonymousClasses() {
|
private void testAnonymousClasses() {
|
||||||
for (int i : new int[] {1, 2}) {
|
for (int i : new int[] {1, 2}) {
|
||||||
check(3, id((switch (i) {
|
check(3, id((switch (i) {
|
||||||
case 1: break new I() {
|
case 1: yield new I() {
|
||||||
public int g() { return 3; }
|
public int g() { return 3; }
|
||||||
};
|
};
|
||||||
default: break (I) () -> { return 3; };
|
default: yield (I) () -> { return 3; };
|
||||||
}).g()));
|
}).g()));
|
||||||
check(3, id((switch (i) {
|
check(3, id((switch (i) {
|
||||||
case 1 -> new I() {
|
case 1 -> new I() {
|
||||||
|
@ -96,7 +98,7 @@ public class ExpressionSwitchBugs {
|
||||||
case 2 -> {
|
case 2 -> {
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
temp += 3;
|
temp += 3;
|
||||||
break temp;
|
yield temp;
|
||||||
}
|
}
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
});
|
});
|
||||||
|
@ -107,7 +109,7 @@ public class ExpressionSwitchBugs {
|
||||||
case 2 -> {
|
case 2 -> {
|
||||||
int temp = 0;
|
int temp = 0;
|
||||||
temp += 3;
|
temp += 3;
|
||||||
break temp;
|
yield temp;
|
||||||
}
|
}
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
});
|
});
|
||||||
|
@ -120,7 +122,7 @@ public class ExpressionSwitchBugs {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void check(int actual, int expected) {
|
private static void check(int actual, int expected) {
|
||||||
if (actual != expected) {
|
if (actual != expected) {
|
||||||
throw new AssertionError("Unexpected result: " + actual);
|
throw new AssertionError("Unexpected result: " + actual);
|
||||||
}
|
}
|
||||||
|
@ -129,4 +131,32 @@ public class ExpressionSwitchBugs {
|
||||||
public interface I {
|
public interface I {
|
||||||
public int g();
|
public int g();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Super {
|
||||||
|
public final int i;
|
||||||
|
|
||||||
|
public Super(int i) {
|
||||||
|
this.i = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
static class C extends Super {
|
||||||
|
public final int i;
|
||||||
|
|
||||||
|
public C(int superI, int i) {
|
||||||
|
super(superI);
|
||||||
|
this.i = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int test(boolean fromSuper) {
|
||||||
|
return switch (fromSuper ? 0 : 1) {
|
||||||
|
case 0 -> {
|
||||||
|
yield super.i;
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
yield this.i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class ExpressionSwitchDA {
|
||||||
int i;
|
int i;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int k = switch (j) {
|
int k = switch (j) {
|
||||||
case 0 -> { i=42; break 42; }
|
case 0 -> { i=42; yield 42; }
|
||||||
default -> i=42;
|
default -> i=42;
|
||||||
};
|
};
|
||||||
System.out.println(i);
|
System.out.println(i);
|
||||||
|
@ -80,7 +80,7 @@ public class ExpressionSwitchDA {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int k = switch (j) {
|
int k = switch (j) {
|
||||||
case 0 -> i=42;
|
case 0 -> i=42;
|
||||||
default -> { i=42; break 42; }
|
default -> { i=42; yield 42; }
|
||||||
};
|
};
|
||||||
System.out.println(i);
|
System.out.println(i);
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,8 @@ public class ExpressionSwitchDA {
|
||||||
int i;
|
int i;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int k = switch (j) {
|
int k = switch (j) {
|
||||||
case 0 -> { i=42; break 42; }
|
case 0 -> { i=42; yield 42; }
|
||||||
default -> { i=42; break 42; }
|
default -> { i=42; yield 42; }
|
||||||
};
|
};
|
||||||
System.out.println(i);
|
System.out.println(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,19 +39,19 @@ public class ExpressionSwitchEmbedding {
|
||||||
int i = 6;
|
int i = 6;
|
||||||
int o = 0;
|
int o = 0;
|
||||||
while (switch (i) {
|
while (switch (i) {
|
||||||
case 1: i = 0; break true;
|
case 1: i = 0; yield true;
|
||||||
case 2: i = 1; break true;
|
case 2: i = 1; yield true;
|
||||||
case 3, 4: i--;
|
case 3, 4: i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> true;
|
case 2 -> true;
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: i--; break switch (i) {
|
default: i--; yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -67,8 +67,8 @@ public class ExpressionSwitchEmbedding {
|
||||||
int i = 6;
|
int i = 6;
|
||||||
int o = 0;
|
int o = 0;
|
||||||
while (switch (i) {
|
while (switch (i) {
|
||||||
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; break true; }
|
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
|
||||||
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; break true; }
|
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
|
||||||
case 3, 4:
|
case 3, 4:
|
||||||
try {
|
try {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
|
@ -76,16 +76,16 @@ public class ExpressionSwitchEmbedding {
|
||||||
i--;
|
i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
try {
|
try {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> throw new ResultException(true);
|
case 2 -> throw new ResultException(true);
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} catch (ResultException ex) {
|
} catch (ResultException ex) {
|
||||||
break ex.result;
|
yield ex.result;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -93,7 +93,7 @@ public class ExpressionSwitchEmbedding {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
i--;
|
i--;
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -111,19 +111,19 @@ public class ExpressionSwitchEmbedding {
|
||||||
int i = 6;
|
int i = 6;
|
||||||
int o = 0;
|
int o = 0;
|
||||||
if (switch (i) {
|
if (switch (i) {
|
||||||
case 1: i = 0; break true;
|
case 1: i = 0; yield true;
|
||||||
case 2: i = 1; break true;
|
case 2: i = 1; yield true;
|
||||||
case 3, 4: i--;
|
case 3, 4: i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
break (switch (i) {
|
yield (switch (i) {
|
||||||
case 2 -> 3;
|
case 2 -> 3;
|
||||||
case 4 -> 5;
|
case 4 -> 5;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
}) == i + 1;
|
}) == i + 1;
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: i--; break switch (i) {
|
default: i--; yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -139,8 +139,8 @@ public class ExpressionSwitchEmbedding {
|
||||||
int i = 6;
|
int i = 6;
|
||||||
int o = 0;
|
int o = 0;
|
||||||
if (switch (i) {
|
if (switch (i) {
|
||||||
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; break true; }
|
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
|
||||||
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; break true; }
|
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
|
||||||
case 3, 4:
|
case 3, 4:
|
||||||
try {
|
try {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
|
@ -148,16 +148,16 @@ public class ExpressionSwitchEmbedding {
|
||||||
i--;
|
i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
try {
|
try {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> throw new ResultException(true);
|
case 2 -> throw new ResultException(true);
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} catch (ResultException ex) {
|
} catch (ResultException ex) {
|
||||||
break ex.result;
|
yield ex.result;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -165,7 +165,7 @@ public class ExpressionSwitchEmbedding {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
i--;
|
i--;
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -182,19 +182,19 @@ public class ExpressionSwitchEmbedding {
|
||||||
{
|
{
|
||||||
int o = 0;
|
int o = 0;
|
||||||
for (int i = 6; (switch (i) {
|
for (int i = 6; (switch (i) {
|
||||||
case 1: i = 0; break true;
|
case 1: i = 0; yield true;
|
||||||
case 2: i = 1; break true;
|
case 2: i = 1; yield true;
|
||||||
case 3, 4: i--;
|
case 3, 4: i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> true;
|
case 2 -> true;
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: i--; break switch (i) {
|
default: i--; yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -209,8 +209,8 @@ public class ExpressionSwitchEmbedding {
|
||||||
{
|
{
|
||||||
int o = 0;
|
int o = 0;
|
||||||
for (int i = 6; (switch (i) {
|
for (int i = 6; (switch (i) {
|
||||||
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; break true; }
|
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
|
||||||
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; break true; }
|
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
|
||||||
case 3, 4:
|
case 3, 4:
|
||||||
try {
|
try {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
|
@ -218,16 +218,16 @@ public class ExpressionSwitchEmbedding {
|
||||||
i--;
|
i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
try {
|
try {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> throw new ResultException(true);
|
case 2 -> throw new ResultException(true);
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} catch (ResultException ex) {
|
} catch (ResultException ex) {
|
||||||
break ex.result;
|
yield ex.result;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -235,7 +235,7 @@ public class ExpressionSwitchEmbedding {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
i--;
|
i--;
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -255,19 +255,19 @@ public class ExpressionSwitchEmbedding {
|
||||||
do {
|
do {
|
||||||
o++;
|
o++;
|
||||||
} while (switch (i) {
|
} while (switch (i) {
|
||||||
case 1: i = 0; break true;
|
case 1: i = 0; yield true;
|
||||||
case 2: i = 1; break true;
|
case 2: i = 1; yield true;
|
||||||
case 3, 4: i--;
|
case 3, 4: i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> true;
|
case 2 -> true;
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: i--; break switch (i) {
|
default: i--; yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
@ -283,8 +283,8 @@ public class ExpressionSwitchEmbedding {
|
||||||
do {
|
do {
|
||||||
o++;
|
o++;
|
||||||
} while (switch (i) {
|
} while (switch (i) {
|
||||||
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; break true; }
|
case 1: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 0; yield true; }
|
||||||
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; break true; }
|
case 2: try { new ExpressionSwitchEmbedding().throwException(); } catch (Throwable t) { i = 1; yield true; }
|
||||||
case 3, 4:
|
case 3, 4:
|
||||||
try {
|
try {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
|
@ -292,16 +292,16 @@ public class ExpressionSwitchEmbedding {
|
||||||
i--;
|
i--;
|
||||||
if (i == 2 || i == 4) {
|
if (i == 2 || i == 4) {
|
||||||
try {
|
try {
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case 2 -> throw new ResultException(true);
|
case 2 -> throw new ResultException(true);
|
||||||
case 4 -> false;
|
case 4 -> false;
|
||||||
default -> throw new IllegalStateException();
|
default -> throw new IllegalStateException();
|
||||||
};
|
};
|
||||||
} catch (ResultException ex) {
|
} catch (ResultException ex) {
|
||||||
break ex.result;
|
yield ex.result;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -309,7 +309,7 @@ public class ExpressionSwitchEmbedding {
|
||||||
new ExpressionSwitchEmbedding().throwException();
|
new ExpressionSwitchEmbedding().throwException();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
i--;
|
i--;
|
||||||
break switch (i) {
|
yield switch (i) {
|
||||||
case -1 -> false;
|
case -1 -> false;
|
||||||
case 3 -> true;
|
case 3 -> true;
|
||||||
default -> true;
|
default -> true;
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class ExpressionSwitchFallThrough {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A: help = "a";
|
case A: help = "a";
|
||||||
case B: help += "b";
|
case B: help += "b";
|
||||||
default: break help;
|
default: yield help;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class ExpressionSwitchFallThrough {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A: help = "a";
|
case A: help = "a";
|
||||||
case B: help += "b";
|
case B: help += "b";
|
||||||
default: break help;
|
default: yield help;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ public class ExpressionSwitchFallThrough1 {
|
||||||
return switch (p) {
|
return switch (p) {
|
||||||
case 0: result += "0";
|
case 0: result += "0";
|
||||||
case 1: result += "1";
|
case 1: result += "1";
|
||||||
break result;
|
yield result;
|
||||||
default: break "other";
|
default: yield "other";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class ExpressionSwitchFallThrough1 {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 0: result += "0";
|
case 0: result += "0";
|
||||||
case 1: result += "1";
|
case 1: result += "1";
|
||||||
break ;
|
break;
|
||||||
default: result = "other";
|
default: result = "other";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ public class ExpressionSwitchFlow {
|
||||||
private String test1(int i) {
|
private String test1(int i) {
|
||||||
return switch (i) {
|
return switch (i) {
|
||||||
case 0 -> {}
|
case 0 -> {}
|
||||||
default -> { break "other"; }
|
default -> { yield "other"; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
private String test2(int i) {
|
private String test2(int i) {
|
||||||
|
@ -27,7 +27,7 @@ public class ExpressionSwitchFlow {
|
||||||
}
|
}
|
||||||
private String test4(int i) {
|
private String test4(int i) {
|
||||||
return switch (i) {
|
return switch (i) {
|
||||||
case 0 -> { break "other"; }
|
case 0 -> { yield "other"; }
|
||||||
default -> {}
|
default -> {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2019, 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
|
||||||
|
@ -43,11 +43,11 @@ public class ExpressionSwitchInExpressionSwitch {
|
||||||
default -> {
|
default -> {
|
||||||
int k = switch (j) {
|
int k = switch (j) {
|
||||||
default -> {
|
default -> {
|
||||||
break 42;
|
yield 42;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
System.out.println("didn't break to the top level");
|
System.out.println("didn't yield to the top level");
|
||||||
break 43;
|
yield 43;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (i!=43) {
|
if (i!=43) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class ExpressionSwitchInfer {
|
||||||
|
|
||||||
String str = switch (param) {
|
String str = switch (param) {
|
||||||
case "" -> {
|
case "" -> {
|
||||||
break 0;
|
yield 0;
|
||||||
} default ->"default";
|
} default ->"default";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@ public class ExpressionSwitchNotExhaustive {
|
||||||
s = "42";
|
s = "42";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break s;
|
yield s;
|
||||||
default:
|
default:
|
||||||
break "43";
|
yield "43";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
enum E {
|
enum E {
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8223305
|
||||||
|
* @summary Verify Tree.toString() related to switch expressions
|
||||||
|
* @modules jdk.compiler
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.tools.*;
|
||||||
|
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
|
||||||
|
public class ExpressionSwitchToString {
|
||||||
|
|
||||||
|
private static final String CODE =
|
||||||
|
"public class C {" +
|
||||||
|
" void t1(Integer i) {" +
|
||||||
|
" switch (i) {" +
|
||||||
|
" case null: i++; break;" +
|
||||||
|
" case 0, 1: i++; break;" +
|
||||||
|
" default: i++; break;" +
|
||||||
|
" }" +
|
||||||
|
" }" +
|
||||||
|
" int t2(Integer i) {" +
|
||||||
|
" return switch (i) {" +
|
||||||
|
" case null: yield 0;" +
|
||||||
|
" case 0, 1: yield 1;" +
|
||||||
|
" default: yield 2;" +
|
||||||
|
" }" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
private static final String EXPECTED =
|
||||||
|
"\n" +
|
||||||
|
"public class C {\n" +
|
||||||
|
" \n" +
|
||||||
|
" void t1(Integer i) {\n" +
|
||||||
|
" switch (i) {\n" +
|
||||||
|
" case null:\n" +
|
||||||
|
" i++;\n" +
|
||||||
|
" break;\n" +
|
||||||
|
" \n" +
|
||||||
|
" case 0, 1:\n" +
|
||||||
|
" i++;\n" +
|
||||||
|
" break;\n" +
|
||||||
|
" \n" +
|
||||||
|
" default:\n" +
|
||||||
|
" i++;\n" +
|
||||||
|
" break;\n" +
|
||||||
|
" \n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" \n" +
|
||||||
|
" int t2(Integer i) {\n" +
|
||||||
|
" return switch (i) {\n" +
|
||||||
|
" case null:\n" +
|
||||||
|
" yield 0;\n" +
|
||||||
|
" \n" +
|
||||||
|
" case 0, 1:\n" +
|
||||||
|
" yield 1;\n" +
|
||||||
|
" \n" +
|
||||||
|
" default:\n" +
|
||||||
|
" yield 2;\n" +
|
||||||
|
" \n" +
|
||||||
|
" };\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
|
assert tool != null;
|
||||||
|
DiagnosticListener<JavaFileObject> noErrors = d -> {};
|
||||||
|
String sourceVersion = Integer.toString(Runtime.version().feature());
|
||||||
|
|
||||||
|
JavacTask ct = (JavacTask) tool.getTask(null, null, noErrors,
|
||||||
|
List.of("-XDdev", "--enable-preview", "-source", sourceVersion), null,
|
||||||
|
Arrays.asList(new MyFileObject(CODE)));
|
||||||
|
String actualCode = ct.parse().iterator().next().toString();
|
||||||
|
actualCode = actualCode.replace(System.getProperty("line.separator"), "\n");
|
||||||
|
if (!EXPECTED.equals(actualCode)) {
|
||||||
|
throw new AssertionError("Unexpected toString outcome: " +
|
||||||
|
actualCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MyFileObject extends SimpleJavaFileObject {
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public MyFileObject(String text) {
|
||||||
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,44 +11,44 @@ public class ExpressionSwitchUnreachable {
|
||||||
int z = 42;
|
int z = 42;
|
||||||
int i = switch (z) {
|
int i = switch (z) {
|
||||||
case 0 -> {
|
case 0 -> {
|
||||||
break 42;
|
yield 42;
|
||||||
System.out.println("Unreachable"); //Unreachable
|
System.out.println("Unreachable"); //Unreachable
|
||||||
}
|
}
|
||||||
default -> 0;
|
default -> 0;
|
||||||
};
|
};
|
||||||
i = switch (z) {
|
i = switch (z) {
|
||||||
case 0 -> {
|
case 0 -> {
|
||||||
break 42;
|
yield 42;
|
||||||
break 42; //Unreachable
|
yield 42; //Unreachable
|
||||||
}
|
}
|
||||||
default -> 0;
|
default -> 0;
|
||||||
};
|
};
|
||||||
i = switch (z) {
|
i = switch (z) {
|
||||||
case 0:
|
case 0:
|
||||||
System.out.println("0");
|
System.out.println("0");
|
||||||
break 42;
|
yield 42;
|
||||||
System.out.println("1"); //Unreachable
|
System.out.println("1"); //Unreachable
|
||||||
default : break 42;
|
default : yield 42;
|
||||||
};
|
};
|
||||||
i = switch (z) {
|
i = switch (z) {
|
||||||
case 0 -> 42;
|
case 0 -> 42;
|
||||||
default -> {
|
default -> {
|
||||||
break 42;
|
yield 42;
|
||||||
System.out.println("Unreachable"); //Unreachable
|
System.out.println("Unreachable"); //Unreachable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
i = switch (z) {
|
i = switch (z) {
|
||||||
case 0: break 42;
|
case 0: yield 42;
|
||||||
default:
|
default:
|
||||||
System.out.println("0");
|
System.out.println("0");
|
||||||
break 42;
|
yield 42;
|
||||||
System.out.println("1"); //Unreachable
|
System.out.println("1"); //Unreachable
|
||||||
};
|
};
|
||||||
i = switch (z) {
|
i = switch (z) {
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
System.out.println("0");
|
System.out.println("0");
|
||||||
break 42;
|
yield 42;
|
||||||
System.out.println("1"); //Unreachable
|
System.out.println("1"); //Unreachable
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,9 @@ public class ParseIncomplete {
|
||||||
" }" +
|
" }" +
|
||||||
" int t2(Integer i) {" +
|
" int t2(Integer i) {" +
|
||||||
" return switch (i) {" +
|
" return switch (i) {" +
|
||||||
" case null: break 0;" +
|
" case null: yield 0;" +
|
||||||
" case 0, 1: break 1;" +
|
" case 0, 1: yield 1;" +
|
||||||
" default: break 2;" +
|
" default: yield 2;" +
|
||||||
" }" +
|
" }" +
|
||||||
" }" +
|
" }" +
|
||||||
"}";
|
"}";
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class SwitchExpressionIsNotAConstant {
|
||||||
int dummy = 1 + switch (i) {
|
int dummy = 1 + switch (i) {
|
||||||
default -> {
|
default -> {
|
||||||
i++;
|
i++;
|
||||||
break 1;
|
yield 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
|
@ -51,7 +51,7 @@ public class SwitchExpressionIsNotAConstant {
|
||||||
case -1 -> 1;
|
case -1 -> 1;
|
||||||
default -> {
|
default -> {
|
||||||
i++;
|
i++;
|
||||||
break 1;
|
yield 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
|
@ -63,7 +63,7 @@ public class SwitchExpressionIsNotAConstant {
|
||||||
int dummy = 1 + switch (i) {
|
int dummy = 1 + switch (i) {
|
||||||
default :
|
default :
|
||||||
i++;
|
i++;
|
||||||
break 1;
|
yield 1;
|
||||||
};
|
};
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
throw new IllegalStateException("Side effects missing.");
|
throw new IllegalStateException("Side effects missing.");
|
||||||
|
@ -72,10 +72,10 @@ public class SwitchExpressionIsNotAConstant {
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
int dummy = 1 + switch (i) {
|
int dummy = 1 + switch (i) {
|
||||||
case -1: break 1;
|
case -1: yield 1;
|
||||||
default:
|
default:
|
||||||
i++;
|
i++;
|
||||||
break 1;
|
yield 1;
|
||||||
};
|
};
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
throw new IllegalStateException("Side effects missing.");
|
throw new IllegalStateException("Side effects missing.");
|
||||||
|
|
|
@ -9,9 +9,9 @@ public class SwitchExpressionScopesIsolated {
|
||||||
|
|
||||||
private String scopesIsolated(int i) {
|
private String scopesIsolated(int i) {
|
||||||
return switch (i) {
|
return switch (i) {
|
||||||
case 0 -> { String res = ""; break res; }
|
case 0 -> { String res = ""; yield res; }
|
||||||
case 1 -> { res = ""; break res; }
|
case 1 -> { res = ""; yield res; }
|
||||||
default -> { res = ""; break res; }
|
default -> { res = ""; yield res; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ import javax.tools.*;
|
||||||
|
|
||||||
import com.sun.source.tree.CompilationUnitTree;
|
import com.sun.source.tree.CompilationUnitTree;
|
||||||
import com.sun.source.tree.SwitchExpressionTree;
|
import com.sun.source.tree.SwitchExpressionTree;
|
||||||
|
import com.sun.source.tree.YieldTree;
|
||||||
import com.sun.source.tree.Tree;
|
import com.sun.source.tree.Tree;
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
import com.sun.source.util.SimpleTreeVisitor;
|
import com.sun.source.util.SimpleTreeVisitor;
|
||||||
|
@ -53,12 +54,13 @@ public class SwitchExpressionSimpleVisitorTest {
|
||||||
String code = "class Test {\n" +
|
String code = "class Test {\n" +
|
||||||
" int t(int i) {\n" +
|
" int t(int i) {\n" +
|
||||||
" return switch(i) {\n" +
|
" return switch(i) {\n" +
|
||||||
" default: break -1;\n" +
|
" default: yield -1;\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}\n";
|
"}\n";
|
||||||
int[] callCount = new int[1];
|
int[] callCount = new int[1];
|
||||||
int[] switchExprNodeCount = new int[1];
|
int[] switchExprNodeCount = new int[1];
|
||||||
|
int[] yieldNodeCount = new int[1];
|
||||||
new TreePathScanner<Void, Void>() {
|
new TreePathScanner<Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void visitSwitchExpression(SwitchExpressionTree node, Void p) {
|
public Void visitSwitchExpression(SwitchExpressionTree node, Void p) {
|
||||||
|
@ -74,11 +76,27 @@ public class SwitchExpressionSimpleVisitorTest {
|
||||||
}, null);
|
}, null);
|
||||||
return super.visitSwitchExpression(node, p);
|
return super.visitSwitchExpression(node, p);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public Void visitYield(YieldTree node, Void p) {
|
||||||
|
node.accept(new SimpleTreeVisitor<Void, Void>() {
|
||||||
|
@Override
|
||||||
|
protected Void defaultAction(Tree defaultActionNode, Void p) {
|
||||||
|
callCount[0]++;
|
||||||
|
if (node == defaultActionNode) {
|
||||||
|
yieldNodeCount[0]++;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
return super.visitYield(node, p);
|
||||||
|
}
|
||||||
}.scan(parse(code), null);
|
}.scan(parse(code), null);
|
||||||
|
|
||||||
if (callCount[0] != 1 || switchExprNodeCount[0] != 1) {
|
if (callCount[0] != 2 || switchExprNodeCount[0] != 1 ||
|
||||||
|
yieldNodeCount[0] != 1) {
|
||||||
throw new AssertionError("Unexpected counts; callCount=" + callCount[0] +
|
throw new AssertionError("Unexpected counts; callCount=" + callCount[0] +
|
||||||
", switchExprNodeCount=" + switchExprNodeCount[0]);
|
", switchExprNodeCount=" + switchExprNodeCount[0] +
|
||||||
|
", yieldNodeCount=" + yieldNodeCount[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,34 +38,34 @@ public class TryCatch {
|
||||||
case 1:
|
case 1:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
};
|
};
|
||||||
case 1 -> {
|
case 1 -> {
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (p + 1) {
|
yield new TryCatch().id(switch (p + 1) {
|
||||||
case 2:
|
case 2:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} - 1);
|
} - 1);
|
||||||
|
@ -83,34 +83,34 @@ public class TryCatch {
|
||||||
case 1:
|
case 1:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
};
|
};
|
||||||
case 1 -> {
|
case 1 -> {
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (p + 1) {
|
yield new TryCatch().id(switch (p + 1) {
|
||||||
case 2:
|
case 2:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} && (x = 1) == 1 && x == 1 ? val : -1);
|
} && (x = 1) == 1 && x == 1 ? val : -1);
|
||||||
|
@ -127,34 +127,34 @@ public class TryCatch {
|
||||||
case B:
|
case B:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
};
|
};
|
||||||
case B -> {
|
case B -> {
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (e.next()) {
|
yield new TryCatch().id(switch (e.next()) {
|
||||||
case C:
|
case C:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} - 1);
|
} - 1);
|
||||||
|
@ -172,34 +172,34 @@ public class TryCatch {
|
||||||
case B:
|
case B:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
};
|
};
|
||||||
case B -> {
|
case B -> {
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (e.next()) {
|
yield new TryCatch().id(switch (e.next()) {
|
||||||
case C:
|
case C:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} && (x = 1) == 1 && x == 1 ? val : -1);
|
} && (x = 1) == 1 && x == 1 ? val : -1);
|
||||||
|
@ -216,34 +216,34 @@ public class TryCatch {
|
||||||
case "c":
|
case "c":
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
};
|
};
|
||||||
case "a" -> {
|
case "a" -> {
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (s + "c") {
|
yield new TryCatch().id(switch (s + "c") {
|
||||||
case "ac":
|
case "ac":
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break val;
|
yield val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} - 1);
|
} - 1);
|
||||||
|
@ -261,34 +261,34 @@ public class TryCatch {
|
||||||
case "c":
|
case "c":
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
};
|
};
|
||||||
case "a" -> {
|
case "a" -> {
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (s + "c") {
|
yield new TryCatch().id(switch (s + "c") {
|
||||||
case "ac":
|
case "ac":
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} && (x = 1) == 1 && x == 1 ? val : -1);
|
} && (x = 1) == 1 && x == 1 ? val : -1);
|
||||||
|
@ -330,75 +330,75 @@ public class TryCatch {
|
||||||
|
|
||||||
static class FieldHolder {
|
static class FieldHolder {
|
||||||
private final int intTest = switch (0) {
|
private final int intTest = switch (0) {
|
||||||
case -1: break -1;
|
case -1: yield -1;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (2) {
|
yield new TryCatch().id(switch (2) {
|
||||||
case 2:
|
case 2:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break 3;
|
yield 3;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static final int intStaticTest = switch (0) {
|
private static final int intStaticTest = switch (0) {
|
||||||
case -1: break -1;
|
case -1: yield -1;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (2) {
|
yield new TryCatch().id(switch (2) {
|
||||||
case 2:
|
case 2:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break -1;
|
yield -1;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break -1;
|
default: yield -1;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break 3;
|
yield 3;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final boolean booleanTest = switch (0) {
|
private final boolean booleanTest = switch (0) {
|
||||||
case -1: break false;
|
case -1: yield false;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (2) {
|
yield new TryCatch().id(switch (2) {
|
||||||
case 2:
|
case 2:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static final boolean booleanStaticTest = switch (0) {
|
private static final boolean booleanStaticTest = switch (0) {
|
||||||
case -1: break false;
|
case -1: yield false;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
break new TryCatch().id(switch (2) {
|
yield new TryCatch().id(switch (2) {
|
||||||
case 2:
|
case 2:
|
||||||
try {
|
try {
|
||||||
new TryCatch().throwException();
|
new TryCatch().throwException();
|
||||||
break false;
|
yield false;
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
default: break false;
|
default: yield false;
|
||||||
});
|
});
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
break true;
|
yield true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
162
test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.java
Normal file
162
test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.java
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8223305
|
||||||
|
* @summary Verify correct warnings w.r.t. yield
|
||||||
|
* @compile/ref=WarnWrongYieldTest.out -source 13 -XDrawDiagnostics -XDshould-stop.at=ATTR WarnWrongYieldTest.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
package t;
|
||||||
|
|
||||||
|
//ERROR - type called yield:
|
||||||
|
import t.WarnWrongYieldTest.yield;
|
||||||
|
|
||||||
|
public class WarnWrongYieldTest {
|
||||||
|
|
||||||
|
// ERROR - class called yield
|
||||||
|
class yield { }
|
||||||
|
|
||||||
|
// OK to have fields called yield
|
||||||
|
String[] yield = null;
|
||||||
|
|
||||||
|
// ERROR - field of type yield
|
||||||
|
yield y;
|
||||||
|
|
||||||
|
// OK to have methods called yield
|
||||||
|
// Nullary yield method
|
||||||
|
String[] yield() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Unary yield method
|
||||||
|
String[] yield(int i) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Binary yield method
|
||||||
|
String[] yield(int i, int j) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK to declare a local called yield
|
||||||
|
void LocalDeclaration1() {
|
||||||
|
int yield;
|
||||||
|
}
|
||||||
|
// OK to declare and initialise a local called yield
|
||||||
|
void LocalDeclaration2() {
|
||||||
|
int yield = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YieldTypedLocals(int i) {
|
||||||
|
// ERROR - Parsed as yield statement, and y1 is unknown
|
||||||
|
yield y1 = null;
|
||||||
|
|
||||||
|
// ERROR - Parsed as yield statement, and y2 is unknown
|
||||||
|
yield y2 = new yield();
|
||||||
|
|
||||||
|
// ERROR - can not create an yield-valued local of type Object
|
||||||
|
Object y3 = new yield();
|
||||||
|
|
||||||
|
// ERROR - can not create a final yield-valued local of type yield
|
||||||
|
final yield y4 = new yield();
|
||||||
|
|
||||||
|
// ERROR - can create a non-final local of type yield using qualified typename
|
||||||
|
WarnWrongYieldTest.yield y5 = new yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MethodInvocation(int i) {
|
||||||
|
|
||||||
|
// OK - can access a field called yield
|
||||||
|
String[] x = this.yield;
|
||||||
|
|
||||||
|
// ERROR - calling nullary yield method using simple name parsed as yield statement
|
||||||
|
yield();
|
||||||
|
// OK - can call nullary yield method using qualified name
|
||||||
|
this.yield();
|
||||||
|
|
||||||
|
// ERROR - Calling unary yield method using simple name is parsed as yield statement
|
||||||
|
yield(2);
|
||||||
|
// OK - calling unary yield method using qualified name
|
||||||
|
this.yield(2);
|
||||||
|
|
||||||
|
// ERROR - Calling binary yield method using simple name is parsed as yield statement
|
||||||
|
yield(2, 2); //error
|
||||||
|
// OK - calling binary yield method using qualified name
|
||||||
|
this.yield(2, 2);
|
||||||
|
|
||||||
|
// ERROR - nullary yield method as receiver is parsed as yield statement
|
||||||
|
yield().toString();
|
||||||
|
// OK - nullary yield method as receiver using qualified name
|
||||||
|
this.yield().toString();
|
||||||
|
|
||||||
|
// ERROR - unary yield method as receiver is parsed as yield statement
|
||||||
|
yield(2).toString();
|
||||||
|
// OK - unary yield method as receiver using qualified name
|
||||||
|
this.yield(2).toString();
|
||||||
|
|
||||||
|
// ERROR - binary yield method as receiver is parsed as yield statement
|
||||||
|
yield(2, 2).toString();
|
||||||
|
// OK - binary yield method as receiver using qualified name
|
||||||
|
this.yield(2, 2).toString();
|
||||||
|
|
||||||
|
// OK - yield method call is in an expression position
|
||||||
|
String str = yield(2).toString();
|
||||||
|
|
||||||
|
//OK - yield is a variable
|
||||||
|
yield.toString();
|
||||||
|
|
||||||
|
// OK - parsed as method call (with qualified local yield as receiver)
|
||||||
|
this.yield.toString();
|
||||||
|
|
||||||
|
yield[0].toString(); //error
|
||||||
|
}
|
||||||
|
|
||||||
|
private void yieldLocalVar1(int i) {
|
||||||
|
int yield = 0;
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
yield++;
|
||||||
|
yield--;
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
yield = 3;
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
yield += 1;
|
||||||
|
|
||||||
|
//OK - yield is a variable and not at the beginning of the statement:
|
||||||
|
yieldLocalVar1(yield);
|
||||||
|
|
||||||
|
//ERROR - unqualified yield method invocation:
|
||||||
|
yieldLocalVar1(yield().length);
|
||||||
|
yieldLocalVar1(yield.class.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void yieldLocalVar2(int i) {
|
||||||
|
int[] yield = new int[1];
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
yield[0] = 5;
|
||||||
|
}
|
||||||
|
}
|
25
test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.out
Normal file
25
test/langtools/tools/javac/switchexpr/WarnWrongYieldTest.out
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
WarnWrongYieldTest.java:39:11: compiler.warn.restricted.type.not.allowed.preview: yield, 13
|
||||||
|
WarnWrongYieldTest.java:45:5: compiler.warn.restricted.type.not.allowed.preview: yield, 13
|
||||||
|
WarnWrongYieldTest.java:72:15: compiler.warn.restricted.type.not.allowed.preview: yield, 13
|
||||||
|
WarnWrongYieldTest.java:75:15: compiler.warn.restricted.type.not.allowed.preview: yield, 13
|
||||||
|
WarnWrongYieldTest.java:81:21: compiler.warn.restricted.type.not.allowed.preview: yield, 13
|
||||||
|
WarnWrongYieldTest.java:93:9: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:98:9: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:103:9: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:108:9: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:113:9: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:118:9: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:123:22: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:152:24: compiler.warn.invalid.yield
|
||||||
|
WarnWrongYieldTest.java:34:28: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:45:5: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:72:9: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:75:9: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:75:24: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:78:25: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:81:15: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:81:30: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:84:27: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:84:43: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
WarnWrongYieldTest.java:153:24: compiler.warn.illegal.ref.to.restricted.type: yield
|
||||||
|
24 warnings
|
46
test/langtools/tools/javac/switchexpr/WrongBreakTest.java
Normal file
46
test/langtools/tools/javac/switchexpr/WrongBreakTest.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8223305
|
||||||
|
* @summary Ensure javac is not crashing for wrong breaks.
|
||||||
|
* @compile/fail/ref=WrongBreakTest.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=FLOW WrongBreakTest.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class WrongBreakTest {
|
||||||
|
|
||||||
|
void test(int i) {
|
||||||
|
int s = 0;
|
||||||
|
int j = switch (s) { default: break; };
|
||||||
|
test(switch (s) { default: yield; });
|
||||||
|
Runnable r = () -> {
|
||||||
|
yield 15;
|
||||||
|
};
|
||||||
|
while (true) {
|
||||||
|
yield 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(Object o) {}
|
||||||
|
}
|
8
test/langtools/tools/javac/switchexpr/WrongBreakTest.out
Normal file
8
test/langtools/tools/javac/switchexpr/WrongBreakTest.out
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
WrongBreakTest.java:36:41: compiler.err.illegal.start.of.expr
|
||||||
|
WrongBreakTest.java:35:39: compiler.err.break.outside.switch.expression
|
||||||
|
WrongBreakTest.java:36:9: compiler.err.ref.ambiguous: test, kindname.method, test(int), WrongBreakTest, kindname.method, test(java.lang.Object), WrongBreakTest
|
||||||
|
WrongBreakTest.java:38:13: compiler.err.no.switch.expression
|
||||||
|
WrongBreakTest.java:41:13: compiler.err.no.switch.expression
|
||||||
|
- compiler.note.preview.filename: WrongBreakTest.java
|
||||||
|
- compiler.note.preview.recompile
|
||||||
|
5 errors
|
225
test/langtools/tools/javac/switchexpr/WrongYieldTest.java
Normal file
225
test/langtools/tools/javac/switchexpr/WrongYieldTest.java
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8223305
|
||||||
|
* @summary Ensure proper errors are returned for yields.
|
||||||
|
* @compile/fail/ref=WrongYieldTest.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=ATTR WrongYieldTest.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
package t;
|
||||||
|
|
||||||
|
//ERROR - type called yield:
|
||||||
|
import t.WrongYieldTest.yield;
|
||||||
|
|
||||||
|
public class WrongYieldTest {
|
||||||
|
|
||||||
|
// ERROR - class called yield
|
||||||
|
class yield { }
|
||||||
|
|
||||||
|
// OK to have fields called yield
|
||||||
|
String[] yield = null;
|
||||||
|
|
||||||
|
// ERROR - field of type yield
|
||||||
|
yield y;
|
||||||
|
|
||||||
|
// OK to have methods called yield
|
||||||
|
// Nullary yield method
|
||||||
|
String[] yield() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Unary yield method
|
||||||
|
String[] yield(int i) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Binary yield method
|
||||||
|
String[] yield(int i, int j) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK to declare a local called yield
|
||||||
|
void LocalDeclaration1() {
|
||||||
|
int yield;
|
||||||
|
}
|
||||||
|
// OK to declare and initialise a local called yield
|
||||||
|
void LocalDeclaration2() {
|
||||||
|
int yield = 42;
|
||||||
|
}
|
||||||
|
// ERROR can't refer to a local called yield in the initialiser
|
||||||
|
void LocalDeclaration3() {
|
||||||
|
int yield = yield + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK yield gets interpreted as an identifier in a local declaration
|
||||||
|
void LocalDeclaration4(int i) {
|
||||||
|
int local = switch (i) {
|
||||||
|
default -> {
|
||||||
|
int yield = yield + 1;
|
||||||
|
yield 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// OK - yield a local called yield
|
||||||
|
void LocalDeclaration5(int i) {
|
||||||
|
int yield = 42;
|
||||||
|
int temp = switch (i) {
|
||||||
|
default -> {
|
||||||
|
yield yield;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void YieldTypedLocals(int i) {
|
||||||
|
// ERROR - Parsed as yield statement, and y1 is unknown
|
||||||
|
yield y1 = null;
|
||||||
|
// ..whereas..
|
||||||
|
// ERROR - parsed as yield statement, which has no switch target
|
||||||
|
Object y1;
|
||||||
|
yield y1 = null;
|
||||||
|
|
||||||
|
// ERROR - Parsed as yield statement, and y2 is unknown
|
||||||
|
yield y2 = new yield();
|
||||||
|
|
||||||
|
// OK - Parsed as yield statement that assigns local y
|
||||||
|
Object y;
|
||||||
|
Object o = switch (i) {
|
||||||
|
default :
|
||||||
|
yield y = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ERROR - Parsed as yield statement that assigns local y,
|
||||||
|
//but the initializer refers to restricted identifier:
|
||||||
|
Object y2;
|
||||||
|
Object o2 = switch (i) {
|
||||||
|
default :
|
||||||
|
yield y2 = new yield();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ERROR - can not create an yield-valued local of type Object
|
||||||
|
Object y3 = new yield();
|
||||||
|
|
||||||
|
// ERROR - can not create a final yield-valued local of type yield
|
||||||
|
final yield y4 = new yield();
|
||||||
|
|
||||||
|
// ERROR - can create a non-final local of type yield using qualified typename
|
||||||
|
WrongYieldTest.yield y5 = new yield();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MethodInvocation(int i) {
|
||||||
|
|
||||||
|
// OK - can access a field called yield
|
||||||
|
String[] x = this.yield;
|
||||||
|
|
||||||
|
// ERROR - calling nullary yield method using simple name parsed as yield statement
|
||||||
|
yield();
|
||||||
|
// OK - can call nullary yield method using qualified name
|
||||||
|
this.yield();
|
||||||
|
|
||||||
|
// ERROR - Calling unary yield method using simple name is parsed as yield statement
|
||||||
|
yield(2);
|
||||||
|
// OK - calling unary yield method using qualified name
|
||||||
|
this.yield(2);
|
||||||
|
|
||||||
|
// ERROR - Calling binary yield method using simple name is parsed as yield statement
|
||||||
|
yield(2, 2); //error
|
||||||
|
// OK - calling binary yield method using qualified name
|
||||||
|
this.yield(2, 2);
|
||||||
|
|
||||||
|
// ERROR - nullary yield method as receiver is parsed as yield statement
|
||||||
|
yield().toString();
|
||||||
|
// OK - nullary yield method as receiver using qualified name
|
||||||
|
this.yield().toString();
|
||||||
|
|
||||||
|
// ERROR - unary yield method as receiver is parsed as yield statement
|
||||||
|
yield(2).toString();
|
||||||
|
// OK - unary yield method as receiver using qualified name
|
||||||
|
this.yield(2).toString();
|
||||||
|
|
||||||
|
// ERROR - binary yield method as receiver is parsed as yield statement
|
||||||
|
yield(2, 2).toString();
|
||||||
|
// OK - binary yield method as receiver using qualified name
|
||||||
|
this.yield(2, 2).toString();
|
||||||
|
|
||||||
|
// OK - yield method call is in an expression position
|
||||||
|
String str = yield(2).toString();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//OK - yield is a variable
|
||||||
|
yield.toString();
|
||||||
|
|
||||||
|
// OK - parsed as method call (with qualified local yield as receiver)
|
||||||
|
this.yield.toString();
|
||||||
|
|
||||||
|
yield[0].toString(); //error
|
||||||
|
|
||||||
|
// OK - parsed as yield statement in switch expression
|
||||||
|
int j = switch (i) {
|
||||||
|
default:
|
||||||
|
yield(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ERROR - second yield is an unreachable statement.
|
||||||
|
x = switch (i) {
|
||||||
|
default: {
|
||||||
|
yield x = null;
|
||||||
|
yield null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void yieldLocalVar1(int i) {
|
||||||
|
int yield = 0;
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
yield++;
|
||||||
|
yield--;
|
||||||
|
|
||||||
|
//ERROR - yield is a statement, but no enclosing switch expr:
|
||||||
|
yield ++i;
|
||||||
|
yield --i;
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
yield = 3;
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
yield += 1;
|
||||||
|
|
||||||
|
//OK - yield is a variable and not at the beginning of the statement:
|
||||||
|
yieldLocalVar1(yield);
|
||||||
|
|
||||||
|
//ERROR - unqualified yield method invocation:
|
||||||
|
yieldLocalVar1(yield().length);
|
||||||
|
yieldLocalVar1(yield.class.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void yieldLocalVar2(int i) {
|
||||||
|
int[] yield = new int[1];
|
||||||
|
|
||||||
|
//OK - yield is a variable:
|
||||||
|
yield[0] = 5;
|
||||||
|
}
|
||||||
|
}
|
29
test/langtools/tools/javac/switchexpr/WrongYieldTest.out
Normal file
29
test/langtools/tools/javac/switchexpr/WrongYieldTest.out
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
WrongYieldTest.java:39:11: compiler.err.restricted.type.not.allowed: yield, 13
|
||||||
|
WrongYieldTest.java:45:5: compiler.err.restricted.type.not.allowed.here: yield
|
||||||
|
WrongYieldTest.java:136:9: compiler.err.invalid.yield
|
||||||
|
WrongYieldTest.java:146:9: compiler.err.invalid.yield
|
||||||
|
WrongYieldTest.java:151:9: compiler.err.invalid.yield
|
||||||
|
WrongYieldTest.java:161:9: compiler.err.invalid.yield
|
||||||
|
WrongYieldTest.java:166:22: compiler.err.invalid.yield
|
||||||
|
WrongYieldTest.java:215:24: compiler.err.invalid.yield
|
||||||
|
WrongYieldTest.java:34:24: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:95:9: compiler.err.no.switch.expression
|
||||||
|
WrongYieldTest.java:95:15: compiler.err.cant.resolve.location: kindname.variable, y1, , , (compiler.misc.location: kindname.class, t.WrongYieldTest, null)
|
||||||
|
WrongYieldTest.java:99:9: compiler.err.no.switch.expression
|
||||||
|
WrongYieldTest.java:102:9: compiler.err.no.switch.expression
|
||||||
|
WrongYieldTest.java:102:15: compiler.err.cant.resolve.location: kindname.variable, y2, , , (compiler.misc.location: kindname.class, t.WrongYieldTest, null)
|
||||||
|
WrongYieldTest.java:102:24: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:116:32: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:120:25: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:123:30: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:126:23: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:126:39: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
WrongYieldTest.java:141:9: compiler.err.no.switch.expression.qualify
|
||||||
|
WrongYieldTest.java:156:9: compiler.err.no.switch.expression
|
||||||
|
WrongYieldTest.java:156:17: compiler.err.cant.deref: int
|
||||||
|
WrongYieldTest.java:201:9: compiler.err.no.switch.expression
|
||||||
|
WrongYieldTest.java:202:9: compiler.err.no.switch.expression
|
||||||
|
WrongYieldTest.java:216:24: compiler.err.illegal.ref.to.restricted.type: yield
|
||||||
|
- compiler.note.preview.filename: WrongYieldTest.java
|
||||||
|
- compiler.note.preview.recompile
|
||||||
|
26 errors
|
116
test/langtools/tools/javac/switchextra/DefiniteAssignment1.java
Normal file
116
test/langtools/tools/javac/switchextra/DefiniteAssignment1.java
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @summary Verify that definite assignment works (legal code)
|
||||||
|
* @compile --enable-preview -source ${jdk.version} DefiniteAssignment1.java
|
||||||
|
* @run main/othervm --enable-preview DefiniteAssignment1
|
||||||
|
*/
|
||||||
|
public class DefiniteAssignment1 {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 0: x = 0; break;
|
||||||
|
default: x = 1; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x != 0)
|
||||||
|
throw new IllegalStateException("Unexpected value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 1: x = 1; break;
|
||||||
|
case 0:
|
||||||
|
default: x = 0; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x != 0)
|
||||||
|
throw new IllegalStateException("Unexpected value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 1: x = 1; break;
|
||||||
|
case 0:
|
||||||
|
default: x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x != 0)
|
||||||
|
throw new IllegalStateException("Unexpected value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 0 -> x = 0;
|
||||||
|
default -> x = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x != 0)
|
||||||
|
throw new IllegalStateException("Unexpected value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch(a) {
|
||||||
|
case 1: x = 1; break;
|
||||||
|
case 0:
|
||||||
|
default: throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("Unexpected value: " + x);
|
||||||
|
} catch (UnsupportedOperationException ex) {
|
||||||
|
//OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 0 -> x = 0;
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x != 0)
|
||||||
|
throw new IllegalStateException("Unexpected value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
A, B, C;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @summary Verify that definite assignment works (illegal code)
|
||||||
|
* @compile/fail/ref=DefiniteAssignment2.out -XDrawDiagnostics --enable-preview -source ${jdk.version} DefiniteAssignment2.java
|
||||||
|
*/
|
||||||
|
public class DefiniteAssignment2 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 0;
|
||||||
|
E e = E.A;
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 0: break;
|
||||||
|
default: x = 1; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 0 -> {}
|
||||||
|
default -> x = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(a) {
|
||||||
|
case 0: x = 0; break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(e) {
|
||||||
|
case A, B, C -> x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(e) {
|
||||||
|
case A, B, C -> { x = 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
switch(e) {
|
||||||
|
case A, B -> { x = 0; }
|
||||||
|
case C -> throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
A, B, C;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
DefiniteAssignment2.java:20:28: compiler.err.var.might.not.have.been.initialized: x
|
||||||
|
DefiniteAssignment2.java:31:28: compiler.err.var.might.not.have.been.initialized: x
|
||||||
|
DefiniteAssignment2.java:42:28: compiler.err.var.might.not.have.been.initialized: x
|
||||||
|
DefiniteAssignment2.java:52:28: compiler.err.var.might.not.have.been.initialized: x
|
||||||
|
DefiniteAssignment2.java:62:28: compiler.err.var.might.not.have.been.initialized: x
|
||||||
|
DefiniteAssignment2.java:73:28: compiler.err.var.might.not.have.been.initialized: x
|
||||||
|
- compiler.note.preview.filename: DefiniteAssignment2.java
|
||||||
|
- compiler.note.preview.recompile
|
||||||
|
6 errors
|
|
@ -30,7 +30,7 @@ public class MultipleLabelsExpression {
|
||||||
private String expression1(T t) {
|
private String expression1(T t) {
|
||||||
return switch (t) {
|
return switch (t) {
|
||||||
case A -> "A";
|
case A -> "A";
|
||||||
case B, C -> { break "B-C"; }
|
case B, C -> { yield "B-C"; }
|
||||||
case D -> "D";
|
case D -> "D";
|
||||||
default -> "other";
|
default -> "other";
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,5 +2,5 @@ VarInImplicitLambdaNegTest01.java:12:28: compiler.err.invalid.lambda.parameter.d
|
||||||
VarInImplicitLambdaNegTest01.java:13: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.implicit.not.allowed)
|
||||||
VarInImplicitLambdaNegTest01.java:14: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.var.and.explicit.not.allowed)
|
||||||
VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
|
VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
|
||||||
VarInImplicitLambdaNegTest01.java:17:52: compiler.err.var.not.allowed.array
|
VarInImplicitLambdaNegTest01.java:17:52: compiler.err.restricted.type.not.allowed.array: var
|
||||||
5 errors
|
5 errors
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- compiler.warn.source.no.bootclasspath: 10
|
- compiler.warn.source.no.bootclasspath: 10
|
||||||
VarInImplicitLambdaNegTest01.java:12:36: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.var.syntax.in.implicit.lambda), 10, 11
|
VarInImplicitLambdaNegTest01.java:12:36: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.var.syntax.in.implicit.lambda), 10, 11
|
||||||
VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
|
VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
|
||||||
VarInImplicitLambdaNegTest01.java:17:52: compiler.err.var.not.allowed.here
|
VarInImplicitLambdaNegTest01.java:17:52: compiler.err.restricted.type.not.allowed.here: var
|
||||||
3 errors
|
3 errors
|
||||||
1 warning
|
1 warning
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue