2323
2424/*
2525 * @test
26- * @bug 8332725
26+ * @bug 8332725 8341901
2727 * @summary Verify the AST model works correctly for binding patterns with var
2828 */
2929
3030import com .sun .source .tree .BindingPatternTree ;
3131import com .sun .source .tree .CompilationUnitTree ;
32+ import com .sun .source .tree .IdentifierTree ;
33+ import com .sun .source .tree .MemberSelectTree ;
3234import com .sun .source .tree .Tree ;
35+ import com .sun .source .tree .VariableTree ;
3336import com .sun .source .util .JavacTask ;
37+ import com .sun .source .util .TreePathScanner ;
3438import com .sun .source .util .TreeScanner ;
39+ import com .sun .source .util .Trees ;
3540import java .net .URI ;
3641import java .util .List ;
3742import java .util .concurrent .atomic .AtomicBoolean ;
43+ import javax .lang .model .type .DeclaredType ;
44+ import javax .lang .model .type .TypeKind ;
45+ import javax .lang .model .type .TypeMirror ;
46+ import javax .tools .Diagnostic ;
47+ import javax .tools .DiagnosticListener ;
3848import javax .tools .JavaCompiler ;
3949import javax .tools .JavaFileObject ;
4050import javax .tools .SimpleJavaFileObject ;
@@ -45,6 +55,7 @@ public class BindingPatternVarTypeModel {
4555
4656 public static void main (String ... args ) throws Exception {
4757 new BindingPatternVarTypeModel ().run ();
58+ new BindingPatternVarTypeModel ().runVarParameterized ();
4859 }
4960
5061 private void run () throws Exception {
@@ -86,4 +97,85 @@ public Void visitBindingPattern(BindingPatternTree node, Void p) {
8697 throw new AssertionError ("Didn't find the binding pattern!" );
8798 }
8899 }
100+
101+ private void runVarParameterized () throws Exception {
102+ JavaFileObject input =
103+ SimpleJavaFileObject .forSource (URI .create ("mem:///Test.java" ),
104+ """
105+ package test;
106+ public class Test {
107+ record R(N.I i) {}
108+ int test(Object o) {
109+ Test.N.I checkType0 = null;
110+ var checkType1 = checkType0;
111+ return switch (o) {
112+ case R(var checkType2) -> 0;
113+ default -> 0;
114+ };
115+ }
116+ static class N<T> {
117+ interface I {}
118+ }
119+ }
120+ """ );
121+ DiagnosticListener <JavaFileObject > noErrors = d -> {
122+ if (d .getKind () == Diagnostic .Kind .ERROR ) {
123+ throw new IllegalStateException (d .toString ());
124+ }
125+ };
126+ JavacTask task =
127+ (JavacTask ) compiler .getTask (null , null , noErrors , null , null , List .of (input ));
128+ CompilationUnitTree cut = task .parse ().iterator ().next ();
129+ Trees trees = Trees .instance (task );
130+
131+ task .analyze ();
132+
133+ new TreePathScanner <Void , Void >() {
134+ private boolean checkAttributes ;
135+ @ Override
136+ public Void visitVariable (VariableTree node , Void p ) {
137+ boolean prevCheckAttributes = checkAttributes ;
138+ try {
139+ checkAttributes |=
140+ node .getName ().toString ().startsWith ("checkType" );
141+ return super .visitVariable (node , p );
142+ } finally {
143+ checkAttributes = prevCheckAttributes ;
144+ }
145+ }
146+
147+ @ Override
148+ public Void visitIdentifier (IdentifierTree node , Void p ) {
149+ checkType ();
150+ return super .visitIdentifier (node , p );
151+ }
152+
153+ @ Override
154+ public Void visitMemberSelect (MemberSelectTree node , Void p ) {
155+ checkType ();
156+ return super .visitMemberSelect (node , p );
157+ }
158+
159+ private void checkType () {
160+ if (!checkAttributes ) {
161+ return ;
162+ }
163+
164+ TypeMirror type = trees .getTypeMirror (getCurrentPath ());
165+
166+ if (type .getKind () == TypeKind .PACKAGE ) {
167+ return ; //OK
168+ }
169+ if (type .getKind () != TypeKind .DECLARED ) {
170+ throw new AssertionError ("Expected a declared type, but got: " +
171+ type .getKind ());
172+ }
173+
174+ if (!((DeclaredType ) type ).getTypeArguments ().isEmpty ()) {
175+ throw new AssertionError ("Unexpected type arguments: " +
176+ ((DeclaredType ) type ).getTypeArguments ());
177+ }
178+ }
179+ }.scan (cut , null );
180+ }
89181}
0 commit comments