From 85a5ae8cb7cb777715224db13481a373ab93edfe Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Tue, 2 Mar 2021 12:02:26 +0000 Subject: [PATCH] 8261606: Surprising behavior of step over in String switch Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Lower.java | 4 +- .../sun/tools/javac/parser/JavacParser.java | 1 + .../com/sun/tools/javac/tree/JCTree.java | 2 + .../com/sun/tools/javac/tree/TreeInfo.java | 3 + .../LineNumberTable/StringSwitchBreaks.java | 71 +++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index 46df9f39d0b..a727023a951 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -3877,7 +3877,9 @@ public class Lower extends TreeTranslator { stmtList.append(switch2); - return make.Block(0L, stmtList.toList()); + JCBlock res = make.Block(0L, stmtList.toList()); + res.endpos = TreeInfo.endPos(tree); + return res; } else { JCSwitchExpression switch2 = make.SwitchExpression(make.Ident(dollar_tmp), lb.toList()); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index 00f42014ac2..e21b3245b0e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -2821,6 +2821,7 @@ public class JavacParser implements Parser { accept(LBRACE); List cases = switchBlockStatementGroups(); JCSwitch t = to(F.at(pos).Switch(selector, cases)); + t.endpos = token.endPos; accept(RBRACE); return t; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index 05aadfe47bb..dbc95891b96 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1246,6 +1246,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public static class JCSwitch extends JCStatement implements SwitchTree { public JCExpression selector; public List cases; + /** Position of closing brace, optional. */ + public int endpos = Position.NOPOS; protected JCSwitch(JCExpression selector, List cases) { this.selector = selector; this.cases = cases; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 3ddba888b93..6430d122198 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -427,6 +427,9 @@ public class TreeInfo { JCTry t = (JCTry) tree; return endPos((t.finalizer != null) ? t.finalizer : (t.catchers.nonEmpty() ? t.catchers.last().body : t.body)); + } else if (tree.hasTag(SWITCH) && + ((JCSwitch) tree).endpos != Position.NOPOS) { + return ((JCSwitch) tree).endpos; } else if (tree.hasTag(SWITCH_EXPRESSION) && ((JCSwitchExpression) tree).endpos != Position.NOPOS) { return ((JCSwitchExpression) tree).endpos; diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java new file mode 100644 index 00000000000..f121122f14d --- /dev/null +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021, 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 8261606 + * @summary Tests a line number table attribute for language constructions in different containers. + * @library /tools/lib /tools/javac/lib ../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * jdk.jdeps/com.sun.tools.classfile + * @build toolbox.ToolBox InMemoryFileManager TestBase + * @build LineNumberTestBase TestCase + * @run main StringSwitchBreaks + */ + +import java.util.List; + +public class StringSwitchBreaks extends LineNumberTestBase { + public static void main(String[] args) throws Exception { + new StringSwitchBreaks().test(); + } + + public void test() throws Exception { + test(List.of(TEST_CASE)); + } + + private static final TestCase[] TEST_CASE = new TestCase[] { + new TestCase(""" + public class StringSwitchBreaks { // 1 + private void test(String s) { // 2 + if (s != null) { // 3 + switch (s) { // 4 + case "a": // 5 + System.out.println("a"); // 6 + break; // 7 + default: // 8 + System.out.println("default"); // 9 + } //10 + } else { //11 + System.out.println("null"); //12 + } //13 + } //14 + } //15 + """, + List.of(1, 3, 4, 6, 7, 9, 10, 12, 14), + "StringSwitchBreaks") + }; + +}