changeset 57820:6351a6bd9253 records-and-sealed

dont allow return statements in canonical constructors
author vromero
date Fri, 06 Sep 2019 16:25:41 -0400
parents 16aa4bd64e80
children cf40c44d5bda d058b932abb6 7e1b4cb3ee6b
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/RecordCompilationTests.java
diffstat 3 files changed, 23 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Fri Sep 06 13:45:50 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Fri Sep 06 16:25:41 2019 -0400
@@ -1267,7 +1267,12 @@
                         log.error(canonicalDecl, Errors.CanonicalConstructorMustBePublic);
                     }
                     if (canonicalInit.type.asMethodType().thrown.stream().anyMatch(exc -> !isUnchecked(exc))) {
-                        log.error(TreeInfo.declarationFor(canonicalInit, env.enclClass), Errors.MethodCantThrowCheckedException);
+                        log.error(canonicalDecl, Errors.MethodCantThrowCheckedException);
+                    }
+                    ReturnFinder initFinder = new ReturnFinder();
+                    initFinder.scan(canonicalDecl.body.stats);
+                    if (initFinder.hasReturn) {
+                        log.error(canonicalDecl, Errors.CanonicalCantHaveReturnStatement);
                     }
                     // let's use the RECORD flag to mark it as the canonical constructor
                     canonicalInit.flags_field |= Flags.RECORD;
@@ -1344,6 +1349,15 @@
 
     }
 
+    class ReturnFinder extends TreeScanner {
+        boolean hasReturn = false;
+
+        @Override
+        public void visitReturn(JCReturn tree) {
+            hasReturn = true;
+        }
+    }
+
     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)) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Sep 06 13:45:50 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Sep 06 16:25:41 2019 -0400
@@ -3486,6 +3486,9 @@
 compiler.err.method.cant.throw.checked.exception=\
     method cannot throw checked exception
 
+compiler.err.canonical.cant.have.return.statement=\
+    canonical constructor can not have return statements
+
 ############################################
 # messages previouly at javac.properties
 
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java	Fri Sep 06 13:45:50 2019 -0400
+++ b/test/langtools/tools/javac/records/RecordCompilationTests.java	Fri Sep 06 16:25:41 2019 -0400
@@ -418,4 +418,9 @@
         assertFail("compiler.err.var.might.not.have.been.initialized", "record R(int x) { # }",
                 "public R { if (x < 0) { this.x = -x; } }");
     }
+
+    public void testReturnInCanonical() {
+        assertFail("compiler.err.canonical.cant.have.return.statement", "record R(int x) { # }",
+                "public R { return; }");
+    }
 }