# HG changeset patch # Parent f155bc4939687693f07e827a51d20770585d899e 8236597: issues inferring type annotations on records diff -r f155bc493968 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Tue Jan 07 13:11:35 2020 -0500 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jan 08 23:57:12 2020 -0500 @@ -57,6 +57,7 @@ import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.jvm.PoolConstant; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.Tag; @@ -1733,6 +1738,7 @@ @SuppressWarnings("preview") public static class RecordComponent extends VarSymbol implements RecordComponentElement { public MethodSymbol accessor; + public JCTree.JCMethodDecl accessorMeth; /** * Construct a record component, given its flags, name, type and owner. diff -r f155bc493968 src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Tue Jan 07 13:11:35 2020 -0500 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Jan 08 23:57:12 2020 -0500 @@ -1129,6 +1129,9 @@ scan(tree.implementing); } scan(tree.defs); + if (tree.sym.isRecord()) { + tree.sym.getRecordComponents().stream().forEach(rc -> scan(rc.accessorMeth)); + } } /** diff -r f155bc493968 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Tue Jan 07 13:11:35 2020 -0500 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Wed Jan 08 23:57:12 2020 -0500 @@ -1040,9 +1040,16 @@ * it could be that some of those annotations are not applicable to the accessor, they will be striped * away later at Check::validateAnnotation */ - JCMethodDecl getter = make.at(tree.pos).MethodDef(make.Modifiers(Flags.PUBLIC | Flags.GENERATED_MEMBER, tree.mods.annotations), + JCMethodDecl getter = make.at(tree.pos). + MethodDef( + make.Modifiers(Flags.PUBLIC | Flags.GENERATED_MEMBER, tree.mods.annotations), tree.sym.name, - make.Type(tree.sym.type), + /* we need to special case for the case when the user declared the type as an ident + * if we don't do that then we can have issues if type annotations are applied to the + * return type: javac issues an error if a type annotation is applied to java.lang.String + * but applying a type annotation to String is kosher + */ + tree.vartype.hasTag(IDENT) ? make.Ident(tree.vartype.type.tsym) : make.Type(tree.sym.type), List.nil(), List.nil(), List.nil(), // thrown @@ -1050,6 +1057,7 @@ null); memberEnter.memberEnter(getter, env); rec.accessor = getter.sym; + rec.accessorMeth = getter; } else if (implSym != null) { rec.accessor = implSym; } @@ -1155,11 +1163,8 @@ field.sym.flags_field &= ~Flags.VARARGS; } // now lets add the accessors - tree.defs.stream() - .filter(t -> t.hasTag(VARDEF)) - .map(t -> (JCVariableDecl) t) - // lets stay clear of adding a forbidden name, javac will fail later anyway - .filter(vd -> (vd.sym.flags_field & RECORD) != 0 && lookupMethod(syms.objectType.tsym, vd.name, List.nil()) == null) + recordFields.stream() + .filter(vd -> (lookupMethod(syms.objectType.tsym, vd.name, List.nil()) == null)) .forEach(vd -> addAccessor(vd, env)); } } diff -r f155bc493968 src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Jan 07 13:11:35 2020 -0500 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jan 08 23:57:12 2020 -0500 @@ -3746,7 +3746,8 @@ ListBuffer tmpParams = new ListBuffer<>(); for (JCVariableDecl param : headerFields) { tmpParams.add(F.at(param) - .VarDef(F.Modifiers(Flags.PARAMETER | param.mods.flags & Flags.VARARGS | param.mods.flags & Flags.FINAL), + // we will get flags plus annotations from the record component + .VarDef(F.Modifiers(Flags.PARAMETER | param.mods.flags & Flags.VARARGS | param.mods.flags & Flags.FINAL, param.mods.annotations), param.name, param.vartype, null)); } methDef.params = tmpParams.toList();