8261205: AssertionError: Cannot add metadata to an intersection type

Reviewed-by: mcimadamore
This commit is contained in:
Vicente Romero 2021-05-20 17:53:00 +00:00
parent 7b98400c81
commit 81f39ed3e0
7 changed files with 170 additions and 8 deletions
src/jdk.compiler/share/classes/com/sun/tools/javac
test/langtools/tools/javac/annotations/typeAnnotations

@ -30,7 +30,6 @@ import javax.lang.model.element.ElementKind;
import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Attribute.Array;
import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
@ -1224,7 +1223,9 @@ public class TypeAnnotations {
.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();
}
@ -1262,7 +1263,7 @@ public class TypeAnnotations {
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.BINDING_VARIABLE) {

@ -27,7 +27,6 @@ package com.sun.tools.javac.comp;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import javax.lang.model.element.ElementKind;
import javax.tools.JavaFileObject;

@ -44,7 +44,6 @@ import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
import static com.sun.tools.javac.tree.JCTree.Tag.VARDEF;
/** Resolves field, method and constructor header, and constructs corresponding Symbols.
*

@ -3327,6 +3327,7 @@ public class JavacParser implements Parser {
*/
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) {
@ -3345,6 +3346,7 @@ public class JavacParser implements Parser {
//error - 'var' and arrays
reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedArray(typeName));
} else {
declaredUsingVar = true;
if(compound)
//error - 'var' in compound local var decl
reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedCompound(typeName));
@ -3357,7 +3359,7 @@ public class JavacParser implements Parser {
}
}
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;
@ -3469,7 +3471,8 @@ public class JavacParser implements Parser {
}
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 }

@ -957,23 +957,35 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
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;
@ -987,6 +999,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
return vartype == null;
}
public boolean declaredUsingVar() {
return declaredUsingVar;
}
@Override
public void accept(Visitor v) { v.visitVarDef(this); }

@ -227,6 +227,12 @@ public class TreeMaker implements JCTree.Factory {
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,138 @@
/*
* 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.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target({ElementType.TYPE_USE, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@interface A {}
class Test {
void kaa() {
@A var c = g(1, 1L);
}
<X> X g(X a, X b) {
return a;
}
void foo() {
bar((@A var s) -> s);
}
void bar(Function<String, String> f) {}
}
""";
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));
}
}
}
}