RFR: JEP 359: Records (Preview) (full code)
Vicente Romero
vicente.romero at oracle.com
Sat Nov 30 18:29:23 UTC 2019
Hi,
I have created another iteration at [1], this is just a delta from last
iteration [2]. Some comments below
[1]
http://cr.openjdk.java.net/~vromero/records.review/all_code/webrev.01_delta.01/
[2] http://cr.openjdk.java.net/~vromero/records.review/all_code/webrev.01
On 11/28/19 1:35 PM, Maurizio Cimadamore wrote:
>
> Hi Vicente,
> generally looks good - few comments below; I tried to focus on areas
> where the compiler code seemed to diverge from the spec, as well on
> pieces of code which look a leftover from previous spec rounds.
>
> * canonical constructors *can* have return statements - compact
> constructors cant; the spec went a bit back and forth on this, but now
> it has settled. Since compact constructors are turned into ordinary
> canonical ones by the parser, I think you need to add an extra check
> for COMPACT_RECORD_CONSTRUCTOR; in other words, this is ok:
>
> record Foo() {
> Foo() { return; } //canonical
> }
>
> this isn't
>
> record Foo() {
> Foo { return; } //compact
> }
>
> but the compiler rejects both. This probably means tweaking the
> diagnostic a bit to say "a compact constructor must not contain
> |return| statements"
>
yes I have modified the code so that the error messages can show
"canonical" or "compact" depending on the case
> * in general, all diagnostics speak about 'canonical constructor'
> regardless of whether the constructor is canonical of compact; while I
> understand the reason behind what we get now, some of the error
> messages can be confusing, especially if you look at the spec, where
> canonical constructor and compact constructor are two different
> concepts. This should be fixed (even if not immediately, in which case
> I'd recommend to file a JBS issue to track that)
>
> * static accessors are allowed - this means that I can do this:
>
> record Foo(int x) {
> public static int x() {return 0; }
>
> public static void main(String[] args) {
> System.err.println(new Foo(42).x());
> }
> }
>
> This will compile and print 0. The classfile will contain the
> following members:
>
> final class Foo extends java.lang.Record {
> public Foo(int);
> public static int x();
> public static void main(java.lang.String[]);
> public java.lang.String toString();
> public final int hashCode();
> public final boolean equals(java.lang.Object);
> }
>
> I believe this is an issue in the compiler, but also in the latest
> spec draft, if I'm not mistaken.
>
yes this is a bug, we are considering updating both the spec and the
compiler. I will submit another iteration as soon as this change is
reflected in both
> * [optional - style] the env.info.isSerializableLambda could become an
> enum { NONE, LAMBDA, SERIALIZABLE_LAMBDA } instead of two boolean
> parameters
>
will do that later, I remember that there were some interactions between
these flags, they are not exclusive
>
> * this code is still rejected with --enable-preview _disabled_:
>
> class X {
> record R(int i) {
> return null;
> }
> }
> class record {}
>
> This gives the error:
>
> Error:
> | records are a preview feature and are disabled by default.
> | (use --enable-preview to enable records)
> | record R(int i) { return null } }
> | ^
> | Error:
> | illegal start of type
> | record R(int i) { return null } }
> | ^
>
> In other words, the parsing logic for members is too aggressive - we
> shouldn't call isRecordStart() in there. If this is not fixed in this
> round, we should keep track with a JBS issue.
>
I have created a follow up issue:
https://bugs.openjdk.java.net/browse/JDK-8235149
> * Are the changes in Tokens really needed?
>
no removed
>
> * Check::checkUnique doesn't seem to use the added 'env' parameter -
> changes should be reverted
>
yep done
>
> * Names.jave - the logic for having forbiddenRecordComponentNames
> could use some refresh - in the latest spec we basically have to ban
> components that have same name as j.l.Object members - so I think we
> can implement the check more directly (e.g. w/o having a set of names).
>
right done, I have created a method that check if a record component
name matches with a parameterless method in Object
> Also, the serialization names are not needed (although I guess they
> will come back at some point).
>
yes they will, I can remove them now but I guess we will need them once
we implement a lint warning
> And, not sure what "get" and "set" are needed for?
>
removed
>
>
> Maurizio
>
thanks,
Vicente
>
> On 28/11/2019 16:05, Vicente Romero wrote:
>> Hi again,
>>
>> Sorry but I realized that I forgot to remove some code on the
>> compiler side. The code removed is small, before we were issuing an
>> error if some serialization methods were declared as record members.
>> That section was removed from the spec. I have prepared another
>> iteration with this change at [1]
>>
>> Thanks,
>> Vicente
>>
>> [1]
>> http://cr.openjdk.java.net/~vromero/records.review/all_code/webrev.01/
>>
>> On 11/27/19 11:37 PM, Vicente Romero wrote:
>>> Hi,
>>>
>>> Please review the code for the records feature at [1]. This webrev
>>> includes all: APIs, runtime, compiler, serialization, javadoc, and
>>> more! Must of the code has been reviewed but there have been some
>>> changes since reviewers saw it. Also this is the first time an
>>> integral webrev is sent out for review. Last changes on top of my
>>> mind since last review iterations:
>>>
>>> On the compiler implementation:
>>> - it has been adapted to the last version of the language spec [2],
>>> as a reference the JVM spec is at [3]. This implied some changes in
>>> determining if a user defined constructor is the canonical or not.
>>> Now if a constructor is override-equivalent to a signature derived
>>> from the record components, then it is considered the canonical
>>> constructor. And any canonical constructor should satisfy a set of
>>> restrictions, see section 8.10.4 Record Constructor Declarations of
>>> the specification.
>>> - It was also added a check to make sure that accessors are not
>>> generic.
>>> - And that the canonical constructor, if user defined, is not
>>> explicitly invoking any other constructor.
>>> - The list of forbidden record component names has also been updated.
>>> - new error messages have been added
>>>
>>> APIs:
>>> - there have been some API editing in java.lang.Record,
>>> java.lang.runtime.ObjectMethods and
>>> java.lang.reflect.RecordComponent, java.io.ObjectInputStream,
>>> javax.lang.model (some visitors were added)
>>>
>>> On the JVM implementation:
>>> - some logging capabilities have been added to classFileParser.cpp
>>> to provide the reason for which the Record attribute has been ignored
>>>
>>> Reflection:
>>> - there are several new changes to the implementation of
>>> java.lang.reflect.RecordComponent apart from the spec changes
>>> mentioned before.
>>>
>>> bug fixes in
>>> - compiler
>>> - serialization,
>>> - JVM, etc
>>>
>>> As a reference the last iteration of the previous reviews can be
>>> found at [4] under folders: compiler, hotspot_runtime, javadoc,
>>> reflection and serialization,
>>>
>>> TIA,
>>> Vicente
>>>
>>> [1]
>>> http://cr.openjdk.java.net/~vromero/records.review/all_code/webrev.00/
>>> [2]
>>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html
>>> [3]
>>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html
>>> [4] http://cr.openjdk.java.net/~vromero/records.review/
>>>
>>
More information about the amber-dev
mailing list