diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index ac181d9b576..4bd11d86723 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -763,36 +763,34 @@ void checkConstraintsOfValueClass(DiagnosticPosition pos, ClassSymbol c) { // dealing with an abstract value or value super class below. Fragment fragment = c.isAbstract() && c.isValueClass() && c == st.tsym ? Fragments.AbstractValueClass(c) : Fragments.SuperclassOfValueClass(c, st); if ((st.tsym.flags() & HASINITBLOCK) != 0) { - log.error(pos, Errors.SuperClassDeclaresInitBlock(fragment)); + log.error(pos, Errors.AbstractValueClassDeclaresInitBlock(fragment)); } - // No instance fields and no arged constructors both mean inner classes - // cannot be super classes for primitive classes. Type encl = st.getEnclosingType(); if (encl != null && encl.hasTag(CLASS)) { - log.error(pos, Errors.SuperClassCannotBeInner(fragment)); + log.error(pos, Errors.AbstractValueClassCannotBeInner(fragment)); } for (Symbol s : st.tsym.members().getSymbols(NON_RECURSIVE)) { switch (s.kind) { case VAR: if ((s.flags() & STATIC) == 0) { - log.error(pos, Errors.SuperFieldNotAllowed(s, fragment)); + log.error(pos, Errors.InstanceFieldNotAllowed(s, fragment)); } break; case MTH: if ((s.flags() & (SYNCHRONIZED | STATIC)) == SYNCHRONIZED) { - log.error(pos, Errors.SuperMethodCannotBeSynchronized(s, c, st)); + log.error(pos, Errors.SuperClassMethodCannotBeSynchronized(s, c, st)); } else if (s.isConstructor()) { MethodSymbol m = (MethodSymbol)s; if (m.getParameters().size() > 0) { - log.error(pos, Errors.SuperConstructorCannotTakeArguments(m, fragment)); + log.error(pos, Errors.AbstractValueClassConstructorCannotTakeArguments(m, fragment)); } else if (m.getTypeParameters().size() > 0) { - log.error(pos, Errors.SuperConstructorCannotBeGeneric(m, fragment)); + log.error(pos, Errors.AbstractValueClassConstructorCannotBeGeneric(m, fragment)); } else if (m.type.getThrownTypes().size() > 0) { - log.error(pos, Errors.SuperConstructorCannotThrow(m, fragment)); + log.error(pos, Errors.AbstractValueClassConstructorCannotThrow(m, fragment)); } else if (protection(m.flags()) > protection(m.owner.flags())) { - log.error(pos, Errors.SuperConstructorAccessRestricted(m, fragment)); + log.error(pos, Errors.AbstractValueClassConstructorHasWeakerAccess(m, fragment)); } else if ((m.flags() & EMPTYNOARGCONSTR) == 0) { - log.error(pos, Errors.SuperNoArgConstructorMustBeEmpty(m, fragment)); + log.error(pos, Errors.AbstractValueClassNoArgConstructorMustBeEmpty(m, fragment)); } } break; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 331384691fd..6511d52bf78 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -3929,13 +3929,6 @@ compiler.err.primitive.classes.not.supported=\ compiler.warn.get.class.compared.with.interface=\ return value of getClass() can never equal the class literal of an interface -# 0: name (of method) -compiler.err.value.class.does.not.support=\ - value classes do not support {0} - -compiler.err.value.class.may.not.extend=\ - inappropriate super class declaration for a value class - compiler.err.this.exposed.prematurely=\ value class instance should not be passed around before being fully initialized @@ -3960,39 +3953,39 @@ compiler.err.concrete.supertype.for.value.class=\ The concrete class {1} is not allowed to be a super class of the value class {0} either directly or indirectly # 0: symbol, 1: symbol, 2: type -compiler.err.super.method.cannot.be.synchronized=\ +compiler.err.super.class.method.cannot.be.synchronized=\ The method {0} in the super class {2} of the value class {1} is synchronized. This is disallowed # 0: symbol, 1: message segment -compiler.err.super.constructor.cannot.take.arguments=\ +compiler.err.abstract.value.class.constructor.cannot.take.arguments=\ {1} defines a constructor {0} that takes arguments. This is disallowed # 0: symbol, 1: message segment -compiler.err.super.constructor.cannot.be.generic=\ +compiler.err.abstract.value.class.constructor.cannot.be.generic=\ {1} defines a generic constructor {0}. This is disallowed # 0: symbol, 1: message segment -compiler.err.super.constructor.cannot.throw=\ +compiler.err.abstract.value.class.constructor.cannot.throw=\ {1} defines a constructor {0} that throws an exception. This is disallowed # 0: symbol, 1: message segment -compiler.err.super.constructor.access.restricted=\ +compiler.err.abstract.value.class.constructor.has.weaker.access=\ {1} defines a constructor {0} with a weaker access privilege than the declaring class. This is disallowed # 0: symbol, 1: message segment -compiler.err.super.field.not.allowed=\ +compiler.err.instance.field.not.allowed=\ {1} defines an instance field {0}. This is disallowed # 0: symbol, 1: message segment -compiler.err.super.no.arg.constructor.must.be.empty=\ +compiler.err.abstract.value.class.no.arg.constructor.must.be.empty=\ {1} defines a nonempty no-arg constructor {0}. This is disallowed # 0: message segment -compiler.err.super.class.declares.init.block=\ +compiler.err.abstract.value.class.declares.init.block=\ {0} declares one or more non-empty instance initializer blocks. This is disallowed. # 0: message segment -compiler.err.super.class.cannot.be.inner=\ +compiler.err.abstract.value.class.cannot.be.inner=\ {0} is an inner class. This is disallowed. # 0: symbol, 1: type diff --git a/test/langtools/tools/javac/diags/examples.not-yet.txt b/test/langtools/tools/javac/diags/examples.not-yet.txt index b6995007565..d1e81c1ac29 100644 --- a/test/langtools/tools/javac/diags/examples.not-yet.txt +++ b/test/langtools/tools/javac/diags/examples.not-yet.txt @@ -209,23 +209,10 @@ compiler.err.preview.without.source.or.release compiler.misc.illegal.signature # the compiler can now detect more non-denotable types before class writing -# Value types +# Value Objects +compiler.misc.feature.value.classes + +# Primitive Classes compiler.err.cyclic.primitive.class.membership -compiler.err.value.class.does.not.support -compiler.err.value.class.may.not.extend -compiler.err.this.exposed.prematurely -compiler.err.concrete.supertype.for.value.class -compiler.err.super.class.cannot.be.inner -compiler.err.super.class.declares.init.block -compiler.err.super.constructor.cannot.take.arguments -compiler.err.super.constructor.access.restricted -compiler.err.super.constructor.cannot.be.generic -compiler.err.super.constructor.cannot.throw -compiler.err.super.field.not.allowed -compiler.err.super.method.cannot.be.synchronized -compiler.err.super.no.arg.constructor.must.be.empty -compiler.err.generic.parameterization.with.primitive.class compiler.misc.feature.primitive.classes -compiler.misc.feature.value.classes -compiler.misc.abstract.value.class -compiler.misc.superclass.of.value.class +compiler.err.generic.parameterization.with.primitive.class \ No newline at end of file diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassCannotBeInner.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassCannotBeInner.java new file mode 100644 index 00000000000..648ebfd8250 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassCannotBeInner.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.cannot.be.inner +// key: compiler.misc.abstract.value.class + +public class AbstractValueClassCannotBeInner { + abstract value class Inner {} +} diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorCannotBeGeneric.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorCannotBeGeneric.java new file mode 100644 index 00000000000..992f2573fc6 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorCannotBeGeneric.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.constructor.cannot.be.generic +// key: compiler.misc.abstract.value.class + +public abstract value class AbstractValueClassConstructorCannotBeGeneric { + <T> AbstractValueClassConstructorCannotBeGeneric() {} +} diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorCannotThrow.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorCannotThrow.java new file mode 100644 index 00000000000..9d736fd492b --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorCannotThrow.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.constructor.cannot.throw +// key: compiler.misc.abstract.value.class + +public abstract value class AbstractValueClassConstructorCannotThrow { + AbstractValueClassConstructorCannotThrow() throws Exception {} +} diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorHasWeakerAccess.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorHasWeakerAccess.java new file mode 100644 index 00000000000..9c9c8c2142e --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassConstructorHasWeakerAccess.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.constructor.has.weaker.access +// key: compiler.misc.abstract.value.class + +public abstract value class AbstractValueClassConstructorHasWeakerAccess { + private AbstractValueClassConstructorHasWeakerAccess() {} +} diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassNoArgConstructorMustBeEmpty.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassNoArgConstructorMustBeEmpty.java new file mode 100644 index 00000000000..47c619bc702 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassNoArgConstructorMustBeEmpty.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.no.arg.constructor.must.be.empty +// key: compiler.misc.abstract.value.class + +public abstract value class AbstractValueClassNoArgConstructorMustBeEmpty { + public AbstractValueClassNoArgConstructorMustBeEmpty() { + System.out.println(""); + } +} diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassWithInstanceInitializer.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassWithInstanceInitializer.java new file mode 100644 index 00000000000..4c3e1eef817 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassWithInstanceInitializer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.declares.init.block +// key: compiler.misc.abstract.value.class + +public abstract value class AbstractValueClassWithInstanceInitializer { + int f; + { f = 42; } +} diff --git a/test/langtools/tools/javac/diags/examples/AbstractValueClassWithNonTrivialConst.java b/test/langtools/tools/javac/diags/examples/AbstractValueClassWithNonTrivialConst.java new file mode 100644 index 00000000000..3edaa5b0ba3 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AbstractValueClassWithNonTrivialConst.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.abstract.value.class.constructor.cannot.take.arguments +// key: compiler.misc.abstract.value.class + +public abstract value class AbstractValueClassWithNonTrivialConst { + AbstractValueClassWithNonTrivialConst(int i) {} +} diff --git a/test/langtools/tools/javac/diags/examples/ConcreteSuperclassOfValueClass.java b/test/langtools/tools/javac/diags/examples/ConcreteSuperclassOfValueClass.java new file mode 100644 index 00000000000..971969ef3bc --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/ConcreteSuperclassOfValueClass.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.concrete.supertype.for.value.class + +public class ConcreteSuperclassOfValueClass { + static abstract value class V extends ConcreteSuperclassOfValueClass {} +} diff --git a/test/langtools/tools/javac/diags/examples/InstanceFieldNotAllowedInValueClass.java b/test/langtools/tools/javac/diags/examples/InstanceFieldNotAllowedInValueClass.java new file mode 100644 index 00000000000..1f2dcd61f1a --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/InstanceFieldNotAllowedInValueClass.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.instance.field.not.allowed +// key: compiler.misc.superclass.of.value.class + +abstract class InstanceFieldNotAllowedInValueClass { + int i; +} + +value class V extends InstanceFieldNotAllowedInValueClass {} diff --git a/test/langtools/tools/javac/diags/examples/SuperClassMethodCannotBeSynchronized.java b/test/langtools/tools/javac/diags/examples/SuperClassMethodCannotBeSynchronized.java new file mode 100644 index 00000000000..462e23a9662 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/SuperClassMethodCannotBeSynchronized.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.super.class.method.cannot.be.synchronized + +public abstract class SuperClassMethodCannotBeSynchronized { + synchronized void foo() {} +} + +value class V extends SuperClassMethodCannotBeSynchronized {} diff --git a/test/langtools/tools/javac/diags/examples/ThisExposedPrematurely.java b/test/langtools/tools/javac/diags/examples/ThisExposedPrematurely.java new file mode 100644 index 00000000000..66297298237 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/ThisExposedPrematurely.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022, 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. + */ + +// key: compiler.err.this.exposed.prematurely + +value class ThisExposedPrematurely { + int x; + ThisExposedPrematurely() { + foo(this); // Error. + x = 10; + } + void foo(ThisExposedPrematurely v) {} +} diff --git a/test/langtools/tools/javac/valhalla/primitive-classes/BinarySuperclassConstraints.out b/test/langtools/tools/javac/valhalla/primitive-classes/BinarySuperclassConstraints.out index 79b7328d304..6a3940ad24b 100644 --- a/test/langtools/tools/javac/valhalla/primitive-classes/BinarySuperclassConstraints.out +++ b/test/langtools/tools/javac/valhalla/primitive-classes/BinarySuperclassConstraints.out @@ -1,8 +1,8 @@ BinarySuperclassConstraints.java:14:15: compiler.err.concrete.supertype.for.value.class: BinarySuperclassConstraints.I0, SuperclassCollections.BadSuper -BinarySuperclassConstraints.java:29:15: compiler.err.super.field.not.allowed: x, (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I6, SuperclassCollections.SuperWithInstanceField) -BinarySuperclassConstraints.java:38:15: compiler.err.super.no.arg.constructor.must.be.empty: SuperclassCollections.SuperWithNonEmptyNoArgCtor(), (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I9, SuperclassCollections.SuperWithNonEmptyNoArgCtor) -BinarySuperclassConstraints.java:40:15: compiler.err.super.constructor.cannot.take.arguments: SuperclassCollections.SuperWithArgedCtor(java.lang.String), (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I10, SuperclassCollections.SuperWithArgedCtor) -BinarySuperclassConstraints.java:42:15: compiler.err.super.no.arg.constructor.must.be.empty: SuperclassCollections.SuperWithInstanceInit(), (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I11, SuperclassCollections.SuperWithInstanceInit) -BinarySuperclassConstraints.java:44:15: compiler.err.super.method.cannot.be.synchronized: foo(), BinarySuperclassConstraints.I12, SuperclassCollections.SuperWithSynchronizedMethod -BinarySuperclassConstraints.java:46:15: compiler.err.super.class.cannot.be.inner: (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I13, SuperclassCollections.InnerSuper) +BinarySuperclassConstraints.java:29:15: compiler.err.instance.field.not.allowed: x, (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I6, SuperclassCollections.SuperWithInstanceField) +BinarySuperclassConstraints.java:38:15: compiler.err.abstract.value.class.no.arg.constructor.must.be.empty: SuperclassCollections.SuperWithNonEmptyNoArgCtor(), (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I9, SuperclassCollections.SuperWithNonEmptyNoArgCtor) +BinarySuperclassConstraints.java:40:15: compiler.err.abstract.value.class.constructor.cannot.take.arguments: SuperclassCollections.SuperWithArgedCtor(java.lang.String), (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I10, SuperclassCollections.SuperWithArgedCtor) +BinarySuperclassConstraints.java:42:15: compiler.err.abstract.value.class.no.arg.constructor.must.be.empty: SuperclassCollections.SuperWithInstanceInit(), (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I11, SuperclassCollections.SuperWithInstanceInit) +BinarySuperclassConstraints.java:44:15: compiler.err.super.class.method.cannot.be.synchronized: foo(), BinarySuperclassConstraints.I12, SuperclassCollections.SuperWithSynchronizedMethod +BinarySuperclassConstraints.java:46:15: compiler.err.abstract.value.class.cannot.be.inner: (compiler.misc.superclass.of.value.class: BinarySuperclassConstraints.I13, SuperclassCollections.InnerSuper) 7 errors diff --git a/test/langtools/tools/javac/valhalla/primitive-classes/SuperclassConstraints.out b/test/langtools/tools/javac/valhalla/primitive-classes/SuperclassConstraints.out index 68b3a12a70b..0eaad3fee90 100644 --- a/test/langtools/tools/javac/valhalla/primitive-classes/SuperclassConstraints.out +++ b/test/langtools/tools/javac/valhalla/primitive-classes/SuperclassConstraints.out @@ -1,8 +1,8 @@ SuperclassConstraints.java:14:15: compiler.err.concrete.supertype.for.value.class: SuperclassConstraints.I0, SuperclassConstraints.BadSuper -SuperclassConstraints.java:44:15: compiler.err.super.field.not.allowed: x, (compiler.misc.superclass.of.value.class: SuperclassConstraints.I6, SuperclassConstraints.SuperWithInstanceField) -SuperclassConstraints.java:76:15: compiler.err.super.no.arg.constructor.must.be.empty: SuperclassConstraints.SuperWithNonEmptyNoArgCtor(), (compiler.misc.superclass.of.value.class: SuperclassConstraints.I9, SuperclassConstraints.SuperWithNonEmptyNoArgCtor) -SuperclassConstraints.java:85:15: compiler.err.super.constructor.cannot.take.arguments: SuperclassConstraints.SuperWithArgedCtor(java.lang.String), (compiler.misc.superclass.of.value.class: SuperclassConstraints.I10, SuperclassConstraints.SuperWithArgedCtor) -SuperclassConstraints.java:98:15: compiler.err.super.class.declares.init.block: (compiler.misc.superclass.of.value.class: SuperclassConstraints.I11, SuperclassConstraints.SuperWithInstanceInit) -SuperclassConstraints.java:106:15: compiler.err.super.method.cannot.be.synchronized: foo(), SuperclassConstraints.I12, SuperclassConstraints.SuperWithSynchronizedMethod -SuperclassConstraints.java:110:15: compiler.err.super.class.cannot.be.inner: (compiler.misc.superclass.of.value.class: SuperclassConstraints.I13, SuperclassConstraints.InnerSuper) +SuperclassConstraints.java:44:15: compiler.err.instance.field.not.allowed: x, (compiler.misc.superclass.of.value.class: SuperclassConstraints.I6, SuperclassConstraints.SuperWithInstanceField) +SuperclassConstraints.java:76:15: compiler.err.abstract.value.class.no.arg.constructor.must.be.empty: SuperclassConstraints.SuperWithNonEmptyNoArgCtor(), (compiler.misc.superclass.of.value.class: SuperclassConstraints.I9, SuperclassConstraints.SuperWithNonEmptyNoArgCtor) +SuperclassConstraints.java:85:15: compiler.err.abstract.value.class.constructor.cannot.take.arguments: SuperclassConstraints.SuperWithArgedCtor(java.lang.String), (compiler.misc.superclass.of.value.class: SuperclassConstraints.I10, SuperclassConstraints.SuperWithArgedCtor) +SuperclassConstraints.java:98:15: compiler.err.abstract.value.class.declares.init.block: (compiler.misc.superclass.of.value.class: SuperclassConstraints.I11, SuperclassConstraints.SuperWithInstanceInit) +SuperclassConstraints.java:106:15: compiler.err.super.class.method.cannot.be.synchronized: foo(), SuperclassConstraints.I12, SuperclassConstraints.SuperWithSynchronizedMethod +SuperclassConstraints.java:110:15: compiler.err.abstract.value.class.cannot.be.inner: (compiler.misc.superclass.of.value.class: SuperclassConstraints.I13, SuperclassConstraints.InnerSuper) 7 errors diff --git a/test/langtools/tools/javac/valhalla/primitive-classes/ValueConcreteSuperType.java b/test/langtools/tools/javac/valhalla/primitive-classes/ValueConcreteSuperType.java deleted file mode 100644 index cbf41442d45..00000000000 --- a/test/langtools/tools/javac/valhalla/primitive-classes/ValueConcreteSuperType.java +++ /dev/null @@ -1,10 +0,0 @@ -/* - * @test /nodynamiccopyright/ - * @bug 8287136 - * @summary [lw4] Javac tolerates abstract value classes that violate constraints for qualifying to be value super classes - * @compile/fail/ref=ValueConcreteSuperType.out -XDrawDiagnostics ValueConcreteSuperType.java - */ - -public class ValueConcreteSuperType { - static abstract value class H extends ValueConcreteSuperType {} // Error: concrete super. -} diff --git a/test/langtools/tools/javac/valhalla/primitive-classes/ValueConcreteSuperType.out b/test/langtools/tools/javac/valhalla/primitive-classes/ValueConcreteSuperType.out deleted file mode 100644 index 64c4bea27ba..00000000000 --- a/test/langtools/tools/javac/valhalla/primitive-classes/ValueConcreteSuperType.out +++ /dev/null @@ -1,2 +0,0 @@ -ValueConcreteSuperType.java:9:27: compiler.err.concrete.supertype.for.value.class: ValueConcreteSuperType.H, ValueConcreteSuperType -1 error diff --git a/test/langtools/tools/javac/valhalla/value-objects/CheckMakeDefault.out b/test/langtools/tools/javac/valhalla/value-objects/CheckMakeDefault.out index b1f3947a65a..fe964ad2410 100644 --- a/test/langtools/tools/javac/valhalla/value-objects/CheckMakeDefault.out +++ b/test/langtools/tools/javac/valhalla/value-objects/CheckMakeDefault.out @@ -1,4 +1,4 @@ -CheckMakeDefault.java:10:20: compiler.err.super.class.cannot.be.inner: (compiler.misc.abstract.value.class: Point.A) +CheckMakeDefault.java:10:20: compiler.err.abstract.value.class.cannot.be.inner: (compiler.misc.abstract.value.class: Point.A) CheckMakeDefault.java:26:32: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: boolean, int) CheckMakeDefault.java:27:33: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: byte, boolean) CheckMakeDefault.java:28:33: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: char, boolean) diff --git a/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java b/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java index bfd04c67e30..7ed26bbbeb3 100644 --- a/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java +++ b/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java @@ -43,6 +43,7 @@ import java.util.List; import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Field; import com.sun.tools.javac.code.Flags; import static org.testng.Assert.assertTrue; @@ -62,13 +63,13 @@ public ValueObjectCompilationTests() { } public void testAbstractValueClassConstraints() { - assertFail("compiler.err.super.field.not.allowed", + assertFail("compiler.err.instance.field.not.allowed", """ abstract value class V { int f; // Error, abstract value class may not declare an instance field. } """); - assertFail("compiler.err.super.class.cannot.be.inner", + assertFail("compiler.err.abstract.value.class.cannot.be.inner", """ class Outer { abstract value class V { @@ -84,13 +85,13 @@ synchronized void foo() { } } """); - assertFail("compiler.err.super.class.declares.init.block", + assertFail("compiler.err.abstract.value.class.declares.init.block", """ abstract value class V { { int f = 42; } // Error, abstract value class may not declare an instance initializer. } """); - assertFail("compiler.err.super.constructor.cannot.take.arguments", + assertFail("compiler.err.abstract.value.class.constructor.cannot.take.arguments", """ abstract value class V { V(int x) {} // Error, abstract value class may not declare a non-trivial constructor. @@ -121,7 +122,7 @@ value class V { } public void testSuperClassConstraints() { - assertFail("compiler.err.super.field.not.allowed", + assertFail("compiler.err.instance.field.not.allowed", """ abstract class I { // identity class since it declares an instance field. int f; @@ -129,15 +130,15 @@ abstract class I { // identity class since it declares an instance field. value class V extends I {} """); - assertFail("compiler.err.super.class.cannot.be.inner", + assertFail("compiler.err.abstract.value.class.cannot.be.inner", """ class Outer { - abstract class I { /* has identity since is an inner class */ } + abstract class I {} // has identity since is an inner class static value class V extends I } """); - assertFail("compiler.err.super.method.cannot.be.synchronized", + assertFail("compiler.err.super.class.method.cannot.be.synchronized", """ abstract class I { // has identity since it declared a synchronized instance method. synchronized void foo() {} @@ -145,7 +146,7 @@ synchronized void foo() {} value class V extends I {} """); - assertFail("compiler.err.super.class.declares.init.block", + assertFail("compiler.err.abstract.value.class.declares.init.block", """ abstract class I { // has identity since it declares an instance initializer { int f = 42; } @@ -153,13 +154,19 @@ abstract class I { // has identity since it declares an instance initializer value class V extends I {} """); - assertFail("compiler.err.super.constructor.cannot.take.arguments", + assertFail("compiler.err.abstract.value.class.constructor.cannot.take.arguments", """ abstract class I { // has identity since it declares a non-trivial constructor I(int x) {} } value class V extends I {} """); + assertFail("compiler.err.concrete.supertype.for.value.class", + """ + class ConcreteSuperType { + static abstract value class V extends ConcreteSuperType {} // Error: concrete super. + } + """); } public void testSynchronizeOnValueInterfaceInstance() { @@ -240,7 +247,7 @@ public void testSemanticsViolations() { value class Base {} class Subclass extends Base {} """); - assertFail("compiler.err.super.class.cannot.be.inner", + assertFail("compiler.err.abstract.value.class.cannot.be.inner", """ class Outer { abstract value class AbsValue {} @@ -285,7 +292,11 @@ value class Point { """); assertFail("compiler.err.illegal.combination.of.modifiers", """ - value identity class IdentityValue {} + value identity class ValueIdentity {} + """); + assertFail("compiler.err.illegal.combination.of.modifiers", + """ + identity value class IdentityValue {} """); assertFail("compiler.err.call.to.super.not.allowed.in.value.ctor", """ @@ -327,6 +338,16 @@ value class V { V() { foo(this); // Error. x = 10; + } + void foo(V v) {} + } + """); + assertOK( + """ + value class V { + int x; + V() { + x = 10; foo(this); // Ok. } void foo(V v) {} @@ -371,35 +392,35 @@ public void testNontrivialConstructor() { assertOK( """ abstract value class V { - public V() { /* trivial ctor */ } + public V() {} // trivial ctor } """ ); - assertFail("compiler.err.super.constructor.access.restricted", + assertFail("compiler.err.abstract.value.class.constructor.has.weaker.access", """ abstract value class V { private V() {} // non-trivial, more restrictive access than the class. } """); - assertFail("compiler.err.super.constructor.cannot.take.arguments", + assertFail("compiler.err.abstract.value.class.constructor.cannot.take.arguments", """ abstract value class V { public V(int x) {} // non-trivial ctor as it declares formal parameters. } """); - assertFail("compiler.err.super.constructor.cannot.be.generic", + assertFail("compiler.err.abstract.value.class.constructor.cannot.be.generic", """ abstract value class V { <T> V() {} // non trivial as it declares type parameters. } """); - assertFail("compiler.err.super.constructor.cannot.throw", + assertFail("compiler.err.abstract.value.class.constructor.cannot.throw", """ abstract value class V { V() throws Exception {} // non-trivial as it throws } """); - assertFail("compiler.err.super.no.arg.constructor.must.be.empty", + assertFail("compiler.err.abstract.value.class.no.arg.constructor.must.be.empty", """ abstract value class V { V() { @@ -572,7 +593,7 @@ non-sealed value class VC implements SI {} ); } - public void testCheckThatAnonymousIsIdentity() throws Exception { + public void testCheckClassFileFlags() throws Exception { for (String source : List.of( """ interface I {} @@ -590,13 +611,130 @@ class Test { class Test { Object o = new Object() {}; } + """, + """ + class Test { + // abstract inner class is implicitly an `identity` class + abstract class Inner {} + } """ )) { File dir = assertOK(true, source); for (final File fileEntry : dir.listFiles()) { if (fileEntry.getName().contains("$")) { ClassFile classFile = ClassFile.read(fileEntry); - assertTrue(classFile.access_flags.flags == Flags.ACC_IDENTITY); + assertTrue((classFile.access_flags.flags & Flags.ACC_IDENTITY) != 0); + } + } + } + + for (String source : List.of( + """ + identity interface I {} + class Sub implements I {} + """, + """ + abstract class A { + // declares a non-static field so it is implicitly an identity class + int i; + } + """, + """ + abstract class A { + // declares a synchronized method so it is implicitly an identity class + synchronized void m() {} + } + """, + """ + class C { + // declares a synchronized method so it is implicitly an identity class + synchronized void m() {} + } + """, + """ + abstract class A { + int i; + // declares an instance initializer so it is implicitly an identity class + { i = 0; } + } + """, + """ + abstract class A { + // declares a non-trivial constructor + A(int i) {} + } + """, + """ + enum E {} + """, + """ + identity enum E {} + """, + """ + record R() {} + """, + """ + identity record R() {} + """ + )) { + File dir = assertOK(true, source); + for (final File fileEntry : dir.listFiles()) { + ClassFile classFile = ClassFile.read(fileEntry); + assertTrue(classFile.access_flags.is(Flags.ACC_IDENTITY)); + assertTrue(!classFile.access_flags.is(Flags.VALUE_CLASS)); + } + } + + { + String source = + """ + value interface I {} + abstract class A implements I {} // not a value class as it doens't have the value modifier + value class Sub extends A {} //implicitly final + """; + File dir = assertOK(true, source); + for (final File fileEntry : dir.listFiles()) { + ClassFile classFile = ClassFile.read(fileEntry); + switch (classFile.getName()) { + case "Sub": + assertTrue((classFile.access_flags.flags & (Flags.VALUE_CLASS | Flags.FINAL)) != 0); + break; + case "A": + assertTrue((classFile.access_flags.flags & (Flags.ABSTRACT)) != 0); + break; + case "I": + assertTrue((classFile.access_flags.flags & (Flags.INTERFACE | Flags.VALUE_CLASS)) != 0); + break; + default: + throw new AssertionError("you shoulnd't be here"); + } + } + } + + for (String source : List.of( + """ + value class V { + int i = 0; + static int j; + } + """, + """ + abstract value class A { + static int j; + } + + value class V extends A { + int i = 0; + } + """ + )) { + File dir = assertOK(true, source); + for (final File fileEntry : dir.listFiles()) { + ClassFile classFile = ClassFile.read(fileEntry); + for (Field field : classFile.fields) { + if (!field.access_flags.is(Flags.STATIC)) { + assertTrue(field.access_flags.is(Flags.FINAL)); + } } } }