Skip to content
Permalink
Browse files
8261205: AssertionError: Cannot add metadata to an intersection type
Reviewed-by: phh
Backport-of: 81f39ed
  • Loading branch information
cushon authored and Paul Hohensee committed Feb 9, 2022
1 parent 18a0883 commit 1db4ed1a62e1c93c4f32d51685723b3ec99aae03
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 5 deletions.
@@ -1209,7 +1209,9 @@ public void visitLambda(JCLambda tree) {
.methodParameter(tree, i, param.vartype.pos);
push(param);
try {
separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
if (!param.declaredUsingVar()) {
separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
}
} finally {
pop();
}
@@ -1247,7 +1249,7 @@ public void visitVarDef(final JCVariableDecl tree) {
final TypeAnnotationPosition pos =
TypeAnnotationPosition.localVariable(currentLambda,
tree.pos);
if (!tree.isImplicitlyTyped()) {
if (!tree.declaredUsingVar()) {
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
}
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
@@ -3054,6 +3054,7 @@ JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean r
*/
JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
boolean reqInit, Comment dc, boolean localDecl, boolean compound) {
boolean declaredUsingVar = false;
type = bracketsOpt(type);
JCExpression init = null;
if (token.kind == EQ) {
@@ -3073,6 +3074,7 @@ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression ty
//error - 'var' and arrays
reportSyntaxError(pos, Errors.VarNotAllowedArray);
} else {
declaredUsingVar = true;
startPos = TreeInfo.getStartPos(mods);
if (startPos == Position.NOPOS)
startPos = TreeInfo.getStartPos(type);
@@ -3082,7 +3084,7 @@ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression ty
}
}
JCVariableDecl result =
toP(F.at(pos).VarDef(mods, name, type, init));
toP(F.at(pos).VarDef(mods, name, type, init, declaredUsingVar));
attach(result, dc);
result.startPos = startPos;
return result;
@@ -3162,7 +3164,8 @@ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean
log.error(token.pos, Errors.VarargsAndOldArraySyntax);
}
type = bracketsOpt(type);
return toP(F.at(pos).VarDef(mods, name, type, null));
return toP(F.at(pos).VarDef(mods, name, type, null,
type != null && type.hasTag(IDENT) && ((JCIdent)type).name == names.var));
}

/** Resources = Resource { ";" Resources }
@@ -922,23 +922,35 @@ public static class JCVariableDecl extends JCStatement implements VariableTree {
public VarSymbol sym;
/** explicit start pos */
public int startPos = Position.NOPOS;
/** declared using `var` */
private boolean declaredUsingVar;

protected JCVariableDecl(JCModifiers mods,
Name name,
JCExpression vartype,
JCExpression init,
VarSymbol sym) {
this(mods, name, vartype, init, sym, false);
}

protected JCVariableDecl(JCModifiers mods,
Name name,
JCExpression vartype,
JCExpression init,
VarSymbol sym,
boolean declaredUsingVar) {
this.mods = mods;
this.name = name;
this.vartype = vartype;
this.init = init;
this.sym = sym;
this.declaredUsingVar = declaredUsingVar;
}

protected JCVariableDecl(JCModifiers mods,
JCExpression nameexpr,
JCExpression vartype) {
this(mods, null, vartype, null, null);
this(mods, null, vartype, null, null, false);
this.nameexpr = nameexpr;
if (nameexpr.hasTag(Tag.IDENT)) {
this.name = ((JCIdent)nameexpr).name;
@@ -952,6 +964,10 @@ public boolean isImplicitlyTyped() {
return vartype == null;
}

public boolean declaredUsingVar() {
return declaredUsingVar;
}

@Override
public void accept(Visitor v) { v.visitVarDef(this); }

@@ -215,6 +215,12 @@ public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype,
return tree;
}

public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, boolean declaredUsingVar) {
JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null, declaredUsingVar);
tree.pos = pos;
return tree;
}

public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
tree.pos = pos;
@@ -0,0 +1,136 @@
/*
* 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 8261205
* @summary check that potentially applicable type annotations are skip if the variable or parameter was declared with var
* @library /tools/lib
* @modules
* jdk.jdeps/com.sun.tools.classfile
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.util
* @build toolbox.ToolBox toolbox.JavacTask
* @run main VariablesDeclaredWithVarTest
*/

import java.util.List;
import java.util.ArrayList;

import java.io.File;
import java.nio.file.Paths;

import java.lang.annotation.*;
import java.util.Arrays;

import com.sun.tools.classfile.*;
import com.sun.tools.javac.util.Assert;

import toolbox.JavacTask;
import toolbox.ToolBox;

public class VariablesDeclaredWithVarTest {
ToolBox tb = new ToolBox();

final String src =
"import java.util.function.*;\n" +
"import java.lang.annotation.ElementType;\n" +
"import java.lang.annotation.Target;\n" +
"\n" +
"@Target({ElementType.TYPE_USE, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})\n" +
"@interface A {}\n" +
"\n" +
"class Test {\n" +
" void kaa() {\n" +
" @A var c = g(1, 1L);\n" +
" }\n" +
"\n" +
" <X> X g(X a, X b) {\n" +
" return a;\n" +
" }\n" +
"\n" +
" void foo() {\n" +
" bar((@A var s) -> s);\n" +
" }\n" +
"\n" +
" void bar(Function<String, String> f) {}\n" +
"}\n";

public static void main(String... args) throws Exception {
new VariablesDeclaredWithVarTest().run();
}

void run() throws Exception {
compileTestClass();
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
"Test.class").toUri()), 0);
}

void compileTestClass() throws Exception {
new JavacTask(tb)
.sources(src)
.run();
}

void checkClassFile(final File cfile, int... taPositions) throws Exception {
ClassFile classFile = ClassFile.read(cfile);
List<TypeAnnotation> annos = new ArrayList<>();
for (Method method : classFile.methods) {
findAnnotations(classFile, method, annos);
String methodName = method.getName(classFile.constant_pool);
Assert.check(annos.size() == 0, "there shouldn't be any type annotations in any method, found " + annos.size() +
" type annotations at method " + methodName);
}
}

void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
}

void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
}

int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
if (cindex != -1) {
Attribute cattr = m.attributes.get(cindex);
assert cattr instanceof Code_attribute;
Code_attribute cAttr = (Code_attribute)cattr;
index = cAttr.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = cAttr.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
}
}
}
}

1 comment on commit 1db4ed1

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 1db4ed1 Feb 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.