diff -r 88502b1cf76f -r 7799a51dbe30 test/langtools/tools/javac/annotations/typeAnnotations/classfile/Patterns.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Patterns.java Wed Nov 27 09:00:01 2019 +0100 @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2009, 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 type annotation on binding patterns + * @library /tools/lib + * @modules java.compiler + * jdk.jdeps/com.sun.tools.javap + * @build toolbox.JavapTask + * @compile --enable-preview -source ${jdk.version} Patterns.java + * @run main/othervm --enable-preview Patterns + */ + +import java.lang.annotation.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import toolbox.JavapTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class Patterns { + + private ToolBox tb = new ToolBox(); + + public static void main(String[] args) throws Exception { + new Patterns().run(); + } + + public void run() throws Exception { + String out = new JavapTask(tb) + .options("-private", + "-verbose") + .classpath(System.getProperty("test.classes")) + .classes("Patterns$SimpleBindingPattern") + .run() + .getOutputLines(Task.OutputKind.DIRECT) + .stream() + .collect(Collectors.joining("\n")); + + String constantPool = out.substring(0, out.indexOf('{')); + + out = out.replaceAll("(?ms) *Code:.*?\n( *RuntimeInvisibleTypeAnnotations:)", "$1"); + out = out.substring(out.indexOf('{')); + out = out.substring(0, out.lastIndexOf('}') + 1); + + String A = snipCPNumber(constantPool, "LPatterns$SimpleBindingPattern$A;"); + String CA = snipCPNumber(constantPool, "LPatterns$SimpleBindingPattern$CA;"); + String value = snipCPNumber(constantPool, "value"); + + String expected = """ + { + private static final java.lang.Object o; + descriptor: Ljava/lang/Object; + flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL + + private static final boolean B1s; + descriptor: Z + flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL + + private static final boolean B1m; + descriptor: Z + flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL + + private final boolean B2s; + descriptor: Z + flags: (0x0012) ACC_PRIVATE, ACC_FINAL + + private final boolean B2m; + descriptor: Z + flags: (0x0012) ACC_PRIVATE, ACC_FINAL + + public Patterns$SimpleBindingPattern(); + descriptor: ()V + flags: (0x0001) ACC_PUBLIC + RuntimeInvisibleTypeAnnotations: + 0: #_A_(): LOCAL_VARIABLE, {start_pc=257, length=18, index=2} + Patterns$SimpleBindingPattern$A + 1: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=297, length=19, index=3} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + 2: #_A_(): LOCAL_VARIABLE, {start_pc=22, length=18, index=1} + Patterns$SimpleBindingPattern$A + 3: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=62, length=18, index=1} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + 4: #_A_(): LOCAL_VARIABLE, {start_pc=101, length=18, index=2} + Patterns$SimpleBindingPattern$A + 5: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=141, length=19, index=3} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + 6: #_A_(): LOCAL_VARIABLE, {start_pc=179, length=18, index=2} + Patterns$SimpleBindingPattern$A + 7: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=219, length=19, index=3} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + + void testPatterns(); + descriptor: ()V + flags: (0x0000) + RuntimeInvisibleTypeAnnotations: + 0: #_A_(): LOCAL_VARIABLE, {start_pc=17, length=18, index=2} + Patterns$SimpleBindingPattern$A + 1: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=57, length=19, index=3} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + + void testPatternsDesugared(); + descriptor: ()V + flags: (0x0000) + RuntimeInvisibleTypeAnnotations: + 0: #_A_(): LOCAL_VARIABLE, {start_pc=17, length=15, index=1; start_pc=51, length=15, index=1} + Patterns$SimpleBindingPattern$A + + static {}; + descriptor: ()V + flags: (0x0008) ACC_STATIC + RuntimeInvisibleTypeAnnotations: + 0: #_A_(): LOCAL_VARIABLE, {start_pc=22, length=18, index=0} + Patterns$SimpleBindingPattern$A + 1: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=61, length=18, index=0} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + 2: #_A_(): LOCAL_VARIABLE, {start_pc=100, length=18, index=1} + Patterns$SimpleBindingPattern$A + 3: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=137, length=18, index=2} + Patterns$SimpleBindingPattern$CA( + value=[@Patterns$SimpleBindingPattern$A,@Patterns$SimpleBindingPattern$A] + ) + }""".replace("_A_", A).replace("_CA_", CA).replace("_value_", value); + + if (!expected.equals(out)) { + throw new AssertionError("Unexpected output:\n" + out + "\nexpected:\n" + expected); + } + } + + private String snipCPNumber(String constantPool, String expectedConstant) { + Matcher m = Pattern.compile("#([0-9]+).*" + Pattern.quote(expectedConstant)) + .matcher(constantPool); + if (!m.find()) { + throw new AssertionError("Cannot find constant pool item"); + } + + return m.group(1); + } + + /*********************** Test class *************************/ + static class SimpleBindingPattern { + @Target(ElementType.TYPE_USE) + @Repeatable(CA.class) + @interface A {} + @Target(ElementType.TYPE_USE) + @interface CA { + public A[] value(); + } + + private static final Object o = ""; + private static final boolean B1s = o instanceof @A String s && s.isEmpty(); + private static final boolean B1m = o instanceof @A @A String s && s.isEmpty(); + private final boolean B2s = o instanceof @A String s && s.isEmpty(); + private final boolean B2m = o instanceof @A @A String s && s.isEmpty(); + + static { + boolean B3s = o instanceof @A String s && s.isEmpty(); + boolean B3m = o instanceof @A @A String s && s.isEmpty(); + } + + { + boolean B4s = o instanceof @A String s && s.isEmpty(); + boolean B4m = o instanceof @A @A String s && s.isEmpty(); + } + + { + boolean B5s = o instanceof @A String s && s.isEmpty(); + boolean B5m = o instanceof @A @A String s && s.isEmpty(); + } + + public SimpleBindingPattern() { + boolean B6s = o instanceof @A String s && s.isEmpty(); + boolean B6m = o instanceof @A @A String s && s.isEmpty(); + } + + void testPatterns() { + boolean B7s = o instanceof @A String s && s.isEmpty(); + boolean B7m = o instanceof @A @A String s && s.isEmpty(); + } + + void testPatternsDesugared() { + @A String s; + boolean B8s = o instanceof String && (s = (String) o) == s && s.isEmpty(); + boolean B8sx = o instanceof String && (s = (String) o) == s && s.isEmpty(); + } + } +}