diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/InstanceOfTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/InstanceOfTree.java index f752f7f3191..793f4be1fc4 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/InstanceOfTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/InstanceOfTree.java @@ -31,6 +31,8 @@ package com.sun.source.tree; * For example: *
  *   expression instanceof type
+ *
+ *   expression instanceof pattern
  * 
* * @jls 15.20.2 The instanceof Operator @@ -48,29 +50,50 @@ public interface InstanceOfTree extends ExpressionTree { ExpressionTree getExpression(); /** - * Returns the type for which to check. - * @return the type + * Returns the type for which to check, or {@code null} if this {@code instanceof} + * uses a pattern other the {@link BindingPatternTree}. + * + *

For {@code instanceof} without a pattern, i.e. in the following form: + *

+     *   expression instanceof type
+     * 
+ * returns the type. + * + *

For {@code instanceof} with a {@link BindingPatternTree}, i.e. in the following form: + *

+     *   expression instanceof type variable_name
+     * 
+ * returns the type. + * + *

For instanceof with a pattern, i.e. in the following form: + *

+     *   expression instanceof pattern
+     * 
+ * returns {@code null}. + * + * @return the type or {@code null} if this {@code instanceof} uses a pattern other than + * the {@linkplain BindingPatternTree} * @see #getPattern() */ Tree getType(); /** - * Returns the tested pattern, or null if this instanceof does not use + * Returns the tested pattern, or {@code null} if this {@code instanceof} does not use * a pattern. * *

For instanceof with a pattern, i.e. in the following form: *

-     *   expression instanceof type variable name
+     *   expression instanceof pattern
      * 
* returns the pattern. * - *

For instanceof without a pattern, i.e. in the following form: + *

For {@code instanceof} without a pattern, i.e. in the following form: *

      *   expression instanceof type
      * 
- * returns null. + * returns {@code null}. * - * @return the tested pattern, or null if this instanceof does not use a pattern + * @return the tested pattern, or {@code null} if this {@code instanceof} does not use a pattern * @since 16 */ PatternTree getPattern(); diff --git a/test/langtools/tools/javac/patterns/InstanceOfModelTest.java b/test/langtools/tools/javac/patterns/InstanceOfModelTest.java new file mode 100644 index 00000000000..b756c9263bd --- /dev/null +++ b/test/langtools/tools/javac/patterns/InstanceOfModelTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2025, 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 8348906 + * @summary Verify the InstanceOfTree model + */ + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.InstanceOfTree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +public class InstanceOfModelTest { + private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + public static void main(String... args) throws Exception { + new InstanceOfModelTest().run(); + } + + private void run() throws Exception { + JavaFileObject input = + SimpleJavaFileObject.forSource(URI.create("mem://Test.java"), + """ + public class Test { + void test(Object o) { + boolean _ = o instanceof R; + boolean _ = o instanceof R r; + boolean _ = o instanceof R(var v); + } + record R(int i) {} + } + """); + JavacTask task = + (JavacTask) compiler.getTask(null, null, null, null, null, List.of(input)); + CompilationUnitTree cut = task.parse().iterator().next(); + + task.analyze(); + + List instanceOf = new ArrayList<>(); + + new TreeScanner() { + @Override + public Void visitInstanceOf(InstanceOfTree node, Void p) { + instanceOf.add(node.getPattern() + ":" + node.getType()); + return super.visitInstanceOf(node, p); + } + }.scan(cut, null); + + List expectedInstanceOf = List.of( + "null:R", + "R r:R", + "R(int v):null" + ); + + if (!Objects.equals(expectedInstanceOf, instanceOf)) { + throw new AssertionError("Expected: " + expectedInstanceOf + ",\n" + + "got: " + instanceOf); + } + } +}