changeset 56894:fe2ae6f104db records-and-sealed

issue an error if the accessor returned type doesnt match exactly with that of the corresponding component
author vromero
date Fri, 21 Jun 2019 16:25:21 -0400
parents 7d943bf13bf3
children 76ea6cf6e40a
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/langtools/tools/javac/records/mandated_members/accessors/BadAccessorsTest.java test/langtools/tools/javac/records/mandated_members/accessors/BadAccessorsTest.out
diffstat 4 files changed, 36 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Fri Jun 21 13:52:53 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Fri Jun 21 16:25:21 2019 -0400
@@ -1072,7 +1072,7 @@
         private void addAccessors(JCVariableDecl tree, Env<AttrContext> env) {
             for (Pair<Accessors.Kind, Name> accessor : tree.accessors) {
                 Type accessorType = accessor.fst.accessorType(syms, tree.sym.type);
-                Symbol implSym = lookupMethod(env.enclClass.sym, accessor.snd, accessorType.getParameterTypes());
+                MethodSymbol implSym = lookupMethod(env.enclClass.sym, accessor.snd, accessorType.getParameterTypes());
                 if (implSym == null || (implSym.flags_field & MANDATED) != 0) {
                     JCMethodDecl getter = make.at(tree.pos).MethodDef(make.Modifiers(Flags.PUBLIC | Flags.MANDATED),
                               accessor.snd,
@@ -1086,8 +1086,13 @@
                               null);
                     memberEnter.memberEnter(getter, env);
                     tree.sym.accessors = tree.sym.accessors.prepend(new Pair<>(accessor.fst, getter.sym));
-                } else if (implSym != null && (implSym.flags() & Flags.PUBLIC) == 0) {
-                    log.error(TreeInfo.declarationFor(implSym, env.enclClass), Errors.MethodMustBePublic(implSym.name));
+                } else if (implSym != null) {
+                    if ((implSym.flags() & Flags.PUBLIC) == 0) {
+                        log.error(TreeInfo.declarationFor(implSym, env.enclClass), Errors.MethodMustBePublic(implSym.name));
+                    }
+                    if (!types.isSameType(implSym.type.getReturnType(), tree.sym.type)) {
+                        log.error(TreeInfo.declarationFor(implSym, env.enclClass), Errors.AccessorReturnTypeDoesntMatch);
+                    }
                 }
             }
         }
@@ -1231,10 +1236,10 @@
         }
     }
 
-    private Symbol lookupMethod(TypeSymbol tsym, Name name, List<Type> argtypes) {
+    private MethodSymbol lookupMethod(TypeSymbol tsym, Name name, List<Type> argtypes) {
         for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
             if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) {
-                return s;
+                return (MethodSymbol) s;
             }
         }
         return null;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jun 21 13:52:53 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jun 21 16:25:21 2019 -0400
@@ -3460,6 +3460,9 @@
 compiler.err.constructor.with.same.erasure.as.canonical=\
     constructor with same erasure as canonical constructor
 
+compiler.err.accessor.return.type.doesnt.match=\
+    type returned by the accessor is not the same as the type of the corresponding record component
+
 ############################################
 # messages previouly at javac.properties
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/records/mandated_members/accessors/BadAccessorsTest.java	Fri Jun 21 16:25:21 2019 -0400
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that the compiler doesn't accept incorrect accessors
+ * @compile/fail/ref=BadAccessorsTest.out -XDrawDiagnostics BadAccessorsTest.java
+ */
+
+import java.util.List;
+
+public class BadAccessorsTest {
+    record R1(int i, int j, int k, List<String> ls) {
+        // accessors has to be public
+        int i() { return i; }
+        private int j() { return j; }
+        protected int k() { return k; }
+        // must match type exactly
+        public List ls() { return ls; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/records/mandated_members/accessors/BadAccessorsTest.out	Fri Jun 21 16:25:21 2019 -0400
@@ -0,0 +1,5 @@
+BadAccessorsTest.java:12:13: compiler.err.method.must.be.public: i
+BadAccessorsTest.java:13:21: compiler.err.method.must.be.public: j
+BadAccessorsTest.java:14:23: compiler.err.method.must.be.public: k
+BadAccessorsTest.java:16:21: compiler.err.accessor.return.type.doesnt.match
+4 errors