Skip to content

Commit 81f39ed

Browse files
author
Vicente Romero
committed
8261205: AssertionError: Cannot add metadata to an intersection type
Reviewed-by: mcimadamore
1 parent 7b98400 commit 81f39ed

File tree

7 files changed

+170
-8
lines changed

7 files changed

+170
-8
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import javax.lang.model.type.TypeKind;
3131
import javax.tools.JavaFileObject;
3232

33-
import com.sun.tools.javac.code.Attribute.Array;
3433
import com.sun.tools.javac.code.Attribute.TypeCompound;
3534
import com.sun.tools.javac.code.Symbol.ClassSymbol;
3635
import com.sun.tools.javac.code.Symbol.TypeSymbol;
@@ -1224,7 +1223,9 @@ public void visitLambda(JCLambda tree) {
12241223
.methodParameter(tree, i, param.vartype.pos);
12251224
push(param);
12261225
try {
1227-
separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
1226+
if (!param.declaredUsingVar()) {
1227+
separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
1228+
}
12281229
} finally {
12291230
pop();
12301231
}
@@ -1262,7 +1263,7 @@ public void visitVarDef(final JCVariableDecl tree) {
12621263
final TypeAnnotationPosition pos =
12631264
TypeAnnotationPosition.localVariable(currentLambda,
12641265
tree.pos);
1265-
if (!tree.isImplicitlyTyped()) {
1266+
if (!tree.declaredUsingVar()) {
12661267
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
12671268
}
12681269
} else if (tree.sym.getKind() == ElementKind.BINDING_VARIABLE) {

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
import java.util.*;
2929
import java.util.function.BiConsumer;
30-
import java.util.stream.Collectors;
3130

3231
import javax.lang.model.element.ElementKind;
3332
import javax.tools.JavaFileObject;

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java

-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import static com.sun.tools.javac.code.Kinds.*;
4545
import static com.sun.tools.javac.code.Kinds.Kind.*;
4646
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
47-
import static com.sun.tools.javac.tree.JCTree.Tag.VARDEF;
4847

4948
/** Resolves field, method and constructor header, and constructs corresponding Symbols.
5049
*

src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -3327,6 +3327,7 @@ JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean r
33273327
*/
33283328
JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
33293329
boolean reqInit, Comment dc, boolean localDecl, boolean compound) {
3330+
boolean declaredUsingVar = false;
33303331
type = bracketsOpt(type);
33313332
JCExpression init = null;
33323333
if (token.kind == EQ) {
@@ -3345,6 +3346,7 @@ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression ty
33453346
//error - 'var' and arrays
33463347
reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedArray(typeName));
33473348
} else {
3349+
declaredUsingVar = true;
33483350
if(compound)
33493351
//error - 'var' in compound local var decl
33503352
reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedCompound(typeName));
@@ -3357,7 +3359,7 @@ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression ty
33573359
}
33583360
}
33593361
JCVariableDecl result =
3360-
toP(F.at(pos).VarDef(mods, name, type, init));
3362+
toP(F.at(pos).VarDef(mods, name, type, init, declaredUsingVar));
33613363
attach(result, dc);
33623364
result.startPos = startPos;
33633365
return result;
@@ -3469,7 +3471,8 @@ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean
34693471
}
34703472
type = bracketsOpt(type);
34713473

3472-
return toP(F.at(pos).VarDef(mods, name, type, null));
3474+
return toP(F.at(pos).VarDef(mods, name, type, null,
3475+
type != null && type.hasTag(IDENT) && ((JCIdent)type).name == names.var));
34733476
}
34743477

34753478
/** Resources = Resource { ";" Resources }

src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -957,23 +957,35 @@ public static class JCVariableDecl extends JCStatement implements VariableTree {
957957
public VarSymbol sym;
958958
/** explicit start pos */
959959
public int startPos = Position.NOPOS;
960+
/** declared using `var` */
961+
private boolean declaredUsingVar;
960962

961963
protected JCVariableDecl(JCModifiers mods,
962964
Name name,
963965
JCExpression vartype,
964966
JCExpression init,
965967
VarSymbol sym) {
968+
this(mods, name, vartype, init, sym, false);
969+
}
970+
971+
protected JCVariableDecl(JCModifiers mods,
972+
Name name,
973+
JCExpression vartype,
974+
JCExpression init,
975+
VarSymbol sym,
976+
boolean declaredUsingVar) {
966977
this.mods = mods;
967978
this.name = name;
968979
this.vartype = vartype;
969980
this.init = init;
970981
this.sym = sym;
982+
this.declaredUsingVar = declaredUsingVar;
971983
}
972984

973985
protected JCVariableDecl(JCModifiers mods,
974986
JCExpression nameexpr,
975987
JCExpression vartype) {
976-
this(mods, null, vartype, null, null);
988+
this(mods, null, vartype, null, null, false);
977989
this.nameexpr = nameexpr;
978990
if (nameexpr.hasTag(Tag.IDENT)) {
979991
this.name = ((JCIdent)nameexpr).name;
@@ -987,6 +999,10 @@ public boolean isImplicitlyTyped() {
987999
return vartype == null;
9881000
}
9891001

1002+
public boolean declaredUsingVar() {
1003+
return declaredUsingVar;
1004+
}
1005+
9901006
@Override
9911007
public void accept(Visitor v) { v.visitVarDef(this); }
9921008

src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java

+6
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype,
227227
return tree;
228228
}
229229

230+
public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, boolean declaredUsingVar) {
231+
JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null, declaredUsingVar);
232+
tree.pos = pos;
233+
return tree;
234+
}
235+
230236
public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
231237
JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
232238
tree.pos = pos;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8261205
27+
* @summary check that potentially applicable type annotations are skip if the variable or parameter was declared with var
28+
* @library /tools/lib
29+
* @modules
30+
* jdk.jdeps/com.sun.tools.classfile
31+
* jdk.compiler/com.sun.tools.javac.api
32+
* jdk.compiler/com.sun.tools.javac.main
33+
* jdk.compiler/com.sun.tools.javac.code
34+
* jdk.compiler/com.sun.tools.javac.util
35+
* @build toolbox.ToolBox toolbox.JavacTask
36+
* @run main VariablesDeclaredWithVarTest
37+
*/
38+
39+
import java.util.List;
40+
import java.util.ArrayList;
41+
42+
import java.io.File;
43+
import java.nio.file.Paths;
44+
45+
import java.lang.annotation.*;
46+
import java.util.Arrays;
47+
48+
import com.sun.tools.classfile.*;
49+
import com.sun.tools.javac.util.Assert;
50+
51+
import toolbox.JavacTask;
52+
import toolbox.ToolBox;
53+
54+
public class VariablesDeclaredWithVarTest {
55+
ToolBox tb = new ToolBox();
56+
57+
final String src =
58+
"""
59+
import java.util.function.*;
60+
import java.lang.annotation.ElementType;
61+
import java.lang.annotation.Target;
62+
63+
@Target({ElementType.TYPE_USE, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
64+
@interface A {}
65+
66+
class Test {
67+
void kaa() {
68+
@A var c = g(1, 1L);
69+
}
70+
71+
<X> X g(X a, X b) {
72+
return a;
73+
}
74+
75+
void foo() {
76+
bar((@A var s) -> s);
77+
}
78+
79+
void bar(Function<String, String> f) {}
80+
}
81+
""";
82+
83+
public static void main(String... args) throws Exception {
84+
new VariablesDeclaredWithVarTest().run();
85+
}
86+
87+
void run() throws Exception {
88+
compileTestClass();
89+
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
90+
"Test.class").toUri()), 0);
91+
}
92+
93+
void compileTestClass() throws Exception {
94+
new JavacTask(tb)
95+
.sources(src)
96+
.run();
97+
}
98+
99+
void checkClassFile(final File cfile, int... taPositions) throws Exception {
100+
ClassFile classFile = ClassFile.read(cfile);
101+
List<TypeAnnotation> annos = new ArrayList<>();
102+
for (Method method : classFile.methods) {
103+
findAnnotations(classFile, method, annos);
104+
String methodName = method.getName(classFile.constant_pool);
105+
Assert.check(annos.size() == 0, "there shouldn't be any type annotations in any method, found " + annos.size() +
106+
" type annotations at method " + methodName);
107+
}
108+
}
109+
110+
void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) {
111+
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
112+
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
113+
}
114+
115+
void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) {
116+
int index = m.attributes.getIndex(cf.constant_pool, name);
117+
if (index != -1) {
118+
Attribute attr = m.attributes.get(index);
119+
assert attr instanceof RuntimeTypeAnnotations_attribute;
120+
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
121+
annos.addAll(Arrays.asList(tAttr.annotations));
122+
}
123+
124+
int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
125+
if (cindex != -1) {
126+
Attribute cattr = m.attributes.get(cindex);
127+
assert cattr instanceof Code_attribute;
128+
Code_attribute cAttr = (Code_attribute)cattr;
129+
index = cAttr.attributes.getIndex(cf.constant_pool, name);
130+
if (index != -1) {
131+
Attribute attr = cAttr.attributes.get(index);
132+
assert attr instanceof RuntimeTypeAnnotations_attribute;
133+
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
134+
annos.addAll(Arrays.asList(tAttr.annotations));
135+
}
136+
}
137+
}
138+
}

0 commit comments

Comments
 (0)