From mark.reinhold at oracle.com Tue May 7 17:55:19 2024 From: mark.reinhold at oracle.com (Mark Reinhold) Date: Tue, 7 May 2024 17:55:19 +0000 Subject: New candidate JEP: 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) Message-ID: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> https://openjdk.org/jeps/477 Summary: Evolve the Java programming language so that beginners can write their first programs without needing to understand language features designed for large programs. Far from using a separate dialect of the language, beginners can write streamlined declarations for single-class programs and then seamlessly expand their programs to use more advanced features as their skills grow. Experienced developers can likewise enjoy writing small programs succinctly, without the need for constructs intended for programming in the large. This is a preview language feature. - Mark From rotanolexandr842 at gmail.com Tue May 7 19:06:28 2024 From: rotanolexandr842 at gmail.com (Olexandr Rotan) Date: Tue, 7 May 2024 22:06:28 +0300 Subject: New candidate JEP: 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) In-Reply-To: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> References: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> Message-ID: Could it be possible to not oblige users to create a void main() method? It would be great if a person that sees java for the first time has the option to write code in plain document without any additional method declarations (even method concept is kind of hard for a complete newbie). I see this accomplishable without any changes to Java language in a following way: 1. Every variable declaration is elevated to the top-level scope of implicitly declared class without initialization. Initialization will be performed later. There could possibly be a problem with var keyword, but if desugaring is performed after attribution, type idents could be explicitly added in the "trans" phase. 2. Every other top-level statement that is not a method or class declaration in a document is wrapped in the anonymous code block of an implicitly declared class. In this scope any "this" refs should be forbidden as well as return statements. 3. Every top-level class and method declaration is elevated to a top-level declaration inside an implicitly declared class. If a class is not static, any instance creation of such classes after desugaring should be created as this.new X(). Constructor declarations for implicitly declared class must be forbidden. 4. Main method is implicitly generated. It creates a new instance of implicitly declared class. This will trigger run of code in anonymous code blocks. I understand that these changes could dramatically change current flow in the implementation, but this way I think this feature could be more friendly towards new users by allowing them to write their first hello world program without having to learn concepts of methods and possibly confusing concepts of void type. Best regards. On Tue, May 7, 2024 at 8:55?PM Mark Reinhold wrote: > https://openjdk.org/jeps/477 > > Summary: Evolve the Java programming language so that beginners can > write their first programs without needing to understand language > features designed for large programs. Far from using a separate > dialect of the language, beginners can write streamlined declarations > for single-class programs and then seamlessly expand their programs to > use more advanced features as their skills grow. Experienced developers > can likewise enjoy writing small programs succinctly, without the need > for constructs intended for programming in the large. This is a preview > language feature. > > - Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Wed May 8 09:59:44 2024 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 8 May 2024 11:59:44 +0200 (CEST) Subject: New candidate JEP: 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) In-Reply-To: References: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> Message-ID: <728855205.19832345.1715162384688.JavaMail.zimbra@univ-eiffel.fr> > From: "Olexandr Rotan" > To: "amber-dev" > Cc: "Gavin Bierman" , "Ron Pressler" > , "jdk-dev" > Sent: Tuesday, May 7, 2024 9:06:28 PM > Subject: Re: New candidate JEP: 477: Implicitly Declared Classes and Instance > Main Methods (Third Preview) > Could it be possible to not oblige users to create a void main() method? It > would be great if a person that sees java for the first time has the option to > write code in plain document without any additional method declarations (even > method concept is kind of hard for a complete newbie). > I see this accomplishable without any changes to Java language in a following > way: > 1. Every variable declaration is elevated to the top-level scope of implicitly > declared class without initialization. Initialization will be performed later. > There could possibly be a problem with var keyword, but if desugaring is > performed after attribution, type idents could be explicitly added in the > "trans" phase. > 2. Every other top-level statement that is not a method or class declaration in > a document is wrapped in the anonymous code block of an implicitly declared > class. In this scope any "this" refs should be forbidden as well as return > statements. > 3. Every top-level class and method declaration is elevated to a top-level > declaration inside an implicitly declared class. If a class is not static, any > instance creation of such classes after desugaring should be created as > this.new X(). Constructor declarations for implicitly declared class must be > forbidden. > 4. Main method is implicitly generated. It creates a new instance of implicitly > declared class. This will trigger run of code in anonymous code blocks. > I understand that these changes could dramatically change current flow in the > implementation, but this way I think this feature could be more friendly > towards new users by allowing them to write their first hello world program > without having to learn concepts of methods and possibly confusing concepts of > void type. We (the amber EG) already rejected that proposal for several reasons. The main reason for me is that the semantics of a field and the semantics of a local variable are very different and here you are trying to promote local variables to fields. > Best regards. regards, R?mi > On Tue, May 7, 2024 at 8:55 PM Mark Reinhold < [ mailto:mark.reinhold at oracle.com > | mark.reinhold at oracle.com ] > wrote: >> [ https://openjdk.org/jeps/477 | https://openjdk.org/jeps/477 ] >> Summary: Evolve the Java programming language so that beginners can >> write their first programs without needing to understand language >> features designed for large programs. Far from using a separate >> dialect of the language, beginners can write streamlined declarations >> for single-class programs and then seamlessly expand their programs to >> use more advanced features as their skills grow. Experienced developers >> can likewise enjoy writing small programs succinctly, without the need >> for constructs intended for programming in the large. This is a preview >> language feature. >> - Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed May 8 14:10:44 2024 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 8 May 2024 10:10:44 -0400 Subject: New candidate JEP: 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) In-Reply-To: References: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> Message-ID: On 5/7/2024 3:06 PM, Olexandr Rotan wrote: > Could it be possible to not oblige users to create a void main() > method? It would be great if a person that sees java for the > first?time has the option to write code in plain document without any > additional method declarations (even method concept is kind of hard > for a complete newbie). This direction ("just let me mix statements and variables at the top level, and let the compiler figure it out") was extensively explored during the design process, for the obvious reasons, but it turned out that this falls afoul of the project goals in a pretty big way, so it was rejected. > I see this accomplishable?without any changes to Java language in a > following way: I think you may be confused on what "Java Language" means.? You talk about "compiler transformations" as if they are outside the language, but the compiler *implements* the language, as specified in the specification.? The compiler has no latitude to accept programs that are not given meaning by the specification.? (To think otherwise is a fatal type error.) > 1. Every variable declaration is elevated?to the top-level scope of > implicitly declared class without initialization. Initialization will > be performed later. There could possibly?be a problem with var > keyword, but if desugaring is performed after attribution, type idents > could be explicitly added in the "trans" phase. > 2. Every other top-level statement that is not a method or class > declaration in a document is wrapped in the anonymous code block?of an > implicitly?declared class. In this scope any "this" refs should be > forbidden as well as return statements. > 3. Every top-level class and method declaration is elevated to a > top-level declaration inside an implicitly declared class. If a class > is not static, any instance creation of such classes after desugaring > should be created?as this.new X(). Constructor declarations for > implicitly declared class must be forbidden. > 4. Main method is implicitly generated. It creates a new instance of > implicitly declared class. This will trigger run of code in anonymous > code blocks. > > I understand that these changes could dramatically change current flow > in the implementation, but this way I think this feature could be more > friendly towards new users by allowing them to write their first hello > world program without having to learn concepts of methods and possibly > confusing concepts of void type. > > Best regards. > > On Tue, May 7, 2024 at 8:55?PM Mark Reinhold > wrote: > > https://openjdk.org/jeps/477 > > ? Summary: Evolve the Java programming language so that beginners can > ? write their first programs without needing to understand language > ? features designed for large programs. Far from using a separate > ? dialect of the language, beginners can write streamlined > declarations > ? for single-class programs and then seamlessly expand their > programs to > ? use more advanced features as their skills grow. Experienced > developers > ? can likewise enjoy writing small programs succinctly, without > the need > ? for constructs intended for programming in the large. This is a > preview > ? language feature. > > - Mark > -------------- next part -------------- An HTML attachment was scrubbed... URL: From johannes.spangenberg at hotmail.de Wed May 8 20:36:17 2024 From: johannes.spangenberg at hotmail.de (Johannes Spangenberg) Date: Wed, 8 May 2024 22:36:17 +0200 Subject: New candidate JEP: 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) In-Reply-To: References: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> Message-ID: Not sure if that belongs here, but what you are describing sounds a lot like JShell Scripts to me. I haven't used JSehll that much, so I may be wrong. Maybe it makes sense to experiment with JShell for these very early stages? JShell has also other benefits. For example it can log which statement is currently executed, making it easier to see what the program is doing. Am 07.05.2024 um 21:06 schrieb Olexandr Rotan: > Could it be possible to not oblige users to create a void main() > method? It would be great if a person that sees java for the > first?time has the option to write code in plain document without any > additional method declarations (even method concept is kind of hard > for a complete newbie). > > I see this accomplishable?without any changes to Java language in a > following way: > > 1. Every variable declaration is elevated?to the top-level scope of > implicitly declared class without initialization. Initialization will > be performed later. There could possibly?be a problem with var > keyword, but if desugaring is performed after attribution, type idents > could be explicitly added in the "trans" phase. > 2. Every other top-level statement that is not a method or class > declaration in a document is wrapped in the anonymous code block?of an > implicitly?declared class. In this scope any "this" refs should be > forbidden as well as return statements. > 3. Every top-level class and method declaration is elevated to a > top-level declaration inside an implicitly declared class. If a class > is not static, any instance creation of such classes after desugaring > should be created?as this.new X(). Constructor declarations for > implicitly declared class must be forbidden. > 4. Main method is implicitly generated. It creates a new instance of > implicitly declared class. This will trigger run of code in anonymous > code blocks. > > I understand that these changes could dramatically change current flow > in the implementation, but this way I think this feature could be more > friendly towards new users by allowing them to write their first hello > world program without having to learn concepts of methods and possibly > confusing concepts of void type. > > Best regards. > > On Tue, May 7, 2024 at 8:55?PM Mark Reinhold > wrote: > > https://openjdk.org/jeps/477 > > ? Summary: Evolve the Java programming language so that beginners can > ? write their first programs without needing to understand language > ? features designed for large programs. Far from using a separate > ? dialect of the language, beginners can write streamlined > declarations > ? for single-class programs and then seamlessly expand their > programs to > ? use more advanced features as their skills grow. Experienced > developers > ? can likewise enjoy writing small programs succinctly, without > the need > ? for constructs intended for programming in the large. This is a > preview > ? language feature. > > - Mark > -------------- next part -------------- An HTML attachment was scrubbed... URL: From duke at openjdk.org Fri May 10 15:42:12 2024 From: duke at openjdk.org (duke) Date: Fri, 10 May 2024 15:42:12 GMT Subject: git: openjdk/amber-docs: Updating JEP list Message-ID: Changeset: 12f7eb3e Author: Gavin Bierman Date: 2024-05-10 16:30:55 +0000 URL: https://git.openjdk.org/amber-docs/commit/12f7eb3e972fb124381cf24bb55c4012bba4710d Updating JEP list ! site/_index.md From duke at openjdk.org Fri May 10 15:44:05 2024 From: duke at openjdk.org (duke) Date: Fri, 10 May 2024 15:44:05 GMT Subject: git: openjdk/amber-docs: Update broken link Message-ID: Changeset: cd637cba Author: Gavin Bierman Date: 2024-05-10 16:43:16 +0000 URL: https://git.openjdk.org/amber-docs/commit/cd637cba9d8233ad69ee77db841e12d4be8b7eba Update broken link ! site/_index.md From archie.cobbs at gmail.com Sat May 11 16:01:20 2024 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Sat, 11 May 2024 11:01:20 -0500 Subject: Flexible constructors and switch pattern incompatibility Message-ID: There is an issue with flexible constructors and certain synthetically-generated try/catch code, for example, when using switch patterns (where a try/catch for MatchException is sprinkled in). Please see https://bugs.openjdk.org/browse/JDK-8332106 for an example. As I understand it, this is due to the same verifier 'uninitializedThis' restriction that prevents bytecode rewriters from building a synthetic try/catch around super() calls, even if the catch clause always rethrows. I may have this muddled, but I believe this restriction disallows an 'uninitializedThis' in a catch clause stack map even if the 'uninitializedThis' is never actually touched. In which case a seemingly obvious fix for this is to relax the restriction, but that's a JVMS change. Are there other options? Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie.cobbs at gmail.com Sat May 11 20:15:01 2024 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Sat, 11 May 2024 15:15:01 -0500 Subject: Flexible constructors and switch pattern incompatibility In-Reply-To: References: Message-ID: Looking at this a little further, I think I remember we already dealt with this, and the JVM restriction referred to below is no longer a problem. In JDK 22, the JVMS was changed to say: The rule for *invokespecial* of an method is the sole motivation for > passing back a distinct exception stack frame. The concern is that when > initializing an object, the *invokespecial* invocation could fail, > leaving the object in a partially initialized, permanently unusable state. > To prevent repeated initialization attempts after an object fails to > initialize the first time, an exception handler must consider any > references to the object stored in local variables to have type top > rather than uninitializedThis or uninitialized(Offset). So then maybe this is just a regular bug, i.e., we need to make an adjustment to how stack maps are generated for code in early initialization contexts. Any confirmation on that appreciated & sorry for the false alarm. -Archie On Sat, May 11, 2024 at 11:01?AM Archie Cobbs wrote: > There is an issue with flexible constructors and certain > synthetically-generated try/catch code, for example, when using switch > patterns (where a try/catch for MatchException is sprinkled in). > > Please see https://bugs.openjdk.org/browse/JDK-8332106 for an example. > > As I understand it, this is due to the same verifier 'uninitializedThis' > restriction that prevents bytecode rewriters from building a synthetic > try/catch around super() calls, even if the catch clause always rethrows. > > I may have this muddled, but I believe this restriction disallows an > 'uninitializedThis' in a catch clause stack map even if the > 'uninitializedThis' is never actually touched. In which case a seemingly > obvious fix for this is to relax the restriction, but that's a JVMS change. > > Are there other options? > > Thanks, > -Archie > > -- > Archie L. Cobbs > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From ron.pressler at oracle.com Sun May 12 18:46:50 2024 From: ron.pressler at oracle.com (Ron Pressler) Date: Sun, 12 May 2024 18:46:50 +0000 Subject: New candidate JEP: 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) In-Reply-To: References: <20240507175517.B3CA16CA058@eggemoggin.niobe.net> Message-ID: <76699CC6-8DB5-4DDF-8C9F-D40F0B7FC4B8@oracle.com> > On 7 May 2024, at 20:06, Olexandr Rotan wrote: > > Could it be possible to not oblige users to create a void main() method? It would be great if a person that sees java for the first time has the option to write code in plain document without any additional method declarations (even method concept is kind of hard for a complete newbie). As is usually the case, the challenge here is not in finding a technical solution to a problem but finding the right problem to solve. While we started out exploring the problem of making it easy to write a basic program, we later realised that a better problem to solve is how to write a basic program that can easily evolve, hence the ?no new mode/dialect? requirement in the JEP. In other words, the requirement is that any code unit in an implicit class could be copied over to an explicit class without changing its semantics. Consequently, all you need to do to ?upgrade? from an implicit class to an explicit class is add a class declaration (and a couple of imports). The top-level code approach doesn?t satisfy this requirement. This is what we mean when we say ?onramp?: there are two requirements for an onramp ? it should be easy to get on and it should make it easy to merge onto the highway. Since all the onramp approach cost us here (compared to top-level code) is adding a main method declaration, it?s a small price to pay to solve what we think is the more appropriate problem to solve. ? Ron From jan.lahoda at oracle.com Mon May 13 14:39:05 2024 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 13 May 2024 16:39:05 +0200 Subject: Flexible constructors and switch pattern incompatibility In-Reply-To: References: Message-ID: <17a21156-d0a6-4680-bc7e-3909da915ba5@oracle.com> Hi Archie, I think this is just a bug. My fix proposal: https://github.com/openjdk/jdk/pull/19217 Thanks, ???? Jan On 11. 05. 24 22:15, Archie Cobbs wrote: > Looking at this a little further, I think I remember we already dealt > with this, and the JVM restriction referred to below is no longer a > problem. > > In JDK 22, the JVMS was changed to say: > > The rule for /invokespecial/ of an || method is the sole > motivation for passing back a distinct exception stack frame. The > concern is that when initializing an object, the /invokespecial/ > invocation could fail, leaving the object in a partially > initialized, permanently unusable state. To prevent repeated > initialization attempts after an object fails to initialize the > first time, an exception handler must consider any references to > the object stored in local variables to have type |top| rather > than |uninitializedThis| or |uninitialized(Offset)|. > > > So then maybe this is just a regular bug, i.e., we need to make an > adjustment to how stack maps are generated for code in early > initialization contexts. Any confirmation on that appreciated & sorry > for the false alarm. > > -Archie > > On Sat, May 11, 2024 at 11:01?AM Archie Cobbs > wrote: > > There is an issue with flexible constructors and certain > synthetically-generated try/catch code, for example, when using > switch patterns (where a try/catch for MatchException is sprinkled > in). > > Please see https://bugs.openjdk.org/browse/JDK-8332106 for an example. > > As I understand it, this is due to the same verifier > 'uninitializedThis' restriction that prevents bytecode rewriters > from building a synthetic try/catch around super() calls, even if > the catch clause always rethrows. > > I may have this muddled, but I believe this restriction disallows > an 'uninitializedThis' in a catch clause stack map even if the > 'uninitializedThis' is never actually touched. In which case a > seemingly obvious fix for this is to relax the restriction, but > that's a JVMS change. > > Are there other options? > > Thanks, > -Archie > > -- > Archie L. Cobbs > > > > -- > Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie.cobbs at gmail.com Mon May 13 15:00:40 2024 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Mon, 13 May 2024 10:00:40 -0500 Subject: Flexible constructors and switch pattern incompatibility In-Reply-To: <17a21156-d0a6-4680-bc7e-3909da915ba5@oracle.com> References: <17a21156-d0a6-4680-bc7e-3909da915ba5@oracle.com> Message-ID: Thanks Jan! On Mon, May 13, 2024 at 9:39?AM Jan Lahoda wrote: > Hi Archie, > > > I think this is just a bug. My fix proposal: > https://github.com/openjdk/jdk/pull/19217 > > > Thanks, > > Jan > > > On 11. 05. 24 22:15, Archie Cobbs wrote: > > Looking at this a little further, I think I remember we already dealt with > this, and the JVM restriction referred to below is no longer a problem. > > In JDK 22, the JVMS was changed to say: > > The rule for *invokespecial* of an method is the sole motivation >> for passing back a distinct exception stack frame. The concern is that when >> initializing an object, the *invokespecial* invocation could fail, >> leaving the object in a partially initialized, permanently unusable state. >> To prevent repeated initialization attempts after an object fails to >> initialize the first time, an exception handler must consider any >> references to the object stored in local variables to have type top >> rather than uninitializedThis or uninitialized(Offset). > > > So then maybe this is just a regular bug, i.e., we need to make an > adjustment to how stack maps are generated for code in early initialization > contexts. Any confirmation on that appreciated & sorry for the false alarm. > > -Archie > > On Sat, May 11, 2024 at 11:01?AM Archie Cobbs > wrote: > >> There is an issue with flexible constructors and certain >> synthetically-generated try/catch code, for example, when using switch >> patterns (where a try/catch for MatchException is sprinkled in). >> >> Please see https://bugs.openjdk.org/browse/JDK-8332106 for an example. >> >> As I understand it, this is due to the same verifier 'uninitializedThis' >> restriction that prevents bytecode rewriters from building a synthetic >> try/catch around super() calls, even if the catch clause always rethrows. >> >> I may have this muddled, but I believe this restriction disallows an >> 'uninitializedThis' in a catch clause stack map even if the >> 'uninitializedThis' is never actually touched. In which case a seemingly >> obvious fix for this is to relax the restriction, but that's a JVMS change. >> >> Are there other options? >> >> Thanks, >> -Archie >> >> -- >> Archie L. Cobbs >> > > > -- > Archie L. Cobbs > > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From eirbjo at gmail.com Tue May 14 16:26:02 2024 From: eirbjo at gmail.com (=?UTF-8?B?RWlyaWsgQmrDuHJzbsO4cw==?=) Date: Tue, 14 May 2024 18:26:02 +0200 Subject: Observation: Module imports and java.io.IO Message-ID: Hi, JEP-477 includes the section "Growing a program", showing how an implicit class can be grown into an ordinary class by wrapping it in a class declaration and adding the necessary (no longer implicit) imports: import static java.io.IO.*; > import java.util.List; // alternatively: import module java.base; The module import of java.base (from JEP-476) strikes me as very elegant in this context in that it provides the learning programmer access to Java's basic APIs in a single import. "Give me the basic java stuff", thanks! The sad thing is that the "basic java stuff" does not seem to include the static methods in java.io.IO. So the learning programmer still needs to add "import static java.io.IO.*". This doubles the number of imports needed, but worse, it introduces the concepts of static imports and wildcard imports! I was thinking it would be really nice if "import module java.base" somehow also included the new IO methods. Has this interaction between JEP-177 and JEP-476 been discussed in the expert group? Thanks, Eirik. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mark.reinhold at oracle.com Tue May 14 19:04:59 2024 From: mark.reinhold at oracle.com (Mark Reinhold) Date: Tue, 14 May 2024 19:04:59 +0000 Subject: New candidate JEP: 482: Flexible Constructor Bodies (Second Preview) Message-ID: <20240514190457.75E066CAC0B@eggemoggin.niobe.net> https://openjdk.org/jeps/482 Summary: In constructors in the Java programming language, allow statements to appear before an explicit constructor invocation, i.e., super(..) or this(..). The statements cannot reference the instance under construction, but they can initialize its fields. Initializing fields before invoking another constructor makes a class more reliable when methods are overridden. This is a preview language feature. - Mark From gavin.bierman at oracle.com Thu May 16 14:24:15 2024 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Thu, 16 May 2024 14:24:15 +0000 Subject: Observation: Module imports and java.io.IO In-Reply-To: References: Message-ID: <157BD9F2-B725-49EA-8AE4-61972E7EE041@oracle.com> Hi Eirik, Thanks for your email. I totally get where you are coming from but I really don?t think anyone would want ?import module? to have the additional semantics of importing all the static members. That then leads us to ?doing something special? which, depending on who gets that special behaviour, is either very non-Java in its feel, or ends up defining a ?beginner?s dialect? which is an explicit non-goal of the JEP. Hope that helps, Gavin PS: Actually in the section on ?growing a program? the static import could just be ?import static java.io.IO.println;?, which at least removes the wildcard. On 14 May 2024, at 17:26, Eirik Bj?rsn?s wrote: Hi, JEP-477 includes the section "Growing a program", showing how an implicit class can be grown into an ordinary class by wrapping it in a class declaration and adding the necessary (no longer implicit) imports: import static java.io.IO.*; import java.util.List; // alternatively: import module java.base; The module import of java.base (from JEP-476) strikes me as very elegant in this context in that it provides the learning programmer access to Java's basic APIs in a single import. "Give me the basic java stuff", thanks! The sad thing is that the "basic java stuff" does not seem to include the static methods in java.io.IO. So the learning programmer still needs to add "import static java.io.IO.*". This doubles the number of imports needed, but worse, it introduces the concepts of static imports and wildcard imports! I was thinking it would be really nice if "import module java.base" somehow also included the new IO methods. Has this interaction between JEP-177 and JEP-476 been discussed in the expert group? Thanks, Eirik. -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu May 16 14:44:59 2024 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 16 May 2024 14:44:59 +0000 Subject: Observation: Module imports and java.io.IO Message-ID: <229BC1B5-FA59-4B7A-96FC-1AB039FF8E1A@oracle.com> ? This was discussed, but only briefly. I agree that it is sad that two import statements are needed rather than one. But the alternative is worse. For many static methods, the class name is really a part of the method name; static-importing ?of? or ?fromString? (which is a very common static method name) would be a terrible idea in almost all cases. For these methods, they are intended to be invoked as ?Date.fromString(s)?; the qualifier is really part of the name. But any kind of bulk-importing of static method names would likely sweep up such inappropriate methods. We explored several ways to provide a controlled static-import that would come along for the ride with package or module import, but each of them seemed likely to cause as many problems as they solved. So in the end, we opted not to generalize, and instead focused on the very small number of static methods that deserve to ?look like they are built into the language.? On May 14, 2024, at 12:26 PM, Eirik Bj?rsn?s > wrote: Hi, JEP-477 includes the section "Growing a program", showing how an implicit class can be grown into an ordinary class by wrapping it in a class declaration and adding the necessary (no longer implicit) imports: import static java.io.IO.*; import java.util.List; // alternatively: import module java.base; The module import of java.base (from JEP-476) strikes me as very elegant in this context in that it provides the learning programmer access to Java's basic APIs in a single import. "Give me the basic java stuff", thanks! The sad thing is that the "basic java stuff" does not seem to include the static methods in java.io.IO. So the learning programmer still needs to add "import static java.io.IO.*". This doubles the number of imports needed, but worse, it introduces the concepts of static imports and wildcard imports! I was thinking it would be really nice if "import module java.base" somehow also included the new IO methods. Has this interaction between JEP-177 and JEP-476 been discussed in the expert group? Thanks, Eirik. -------------- next part -------------- An HTML attachment was scrubbed... URL: From clayton.m.walker at gmail.com Mon May 20 05:59:30 2024 From: clayton.m.walker at gmail.com (Clayton Walker) Date: Sun, 19 May 2024 23:59:30 -0600 Subject: Module imports fail in a module-info.java file Message-ID: I tried adding a module import to the top of a module file and got a compilation error. import module org.jspecify; @NullMarked module org.example.mymodule { requires org.jspecify; } With the error An exception has occurred in the compiler (23-ea). Please file a bug against the Java compiler via the Java bug reporting page ( https://bugreport.java.com) after checking the Bug Database ( https://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you. java.lang.AssertionError at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155) at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.visitTree(TreeScanner.java:415) at jdk.compiler/com.sun.tools.javac.tree.JCTree$Visitor.visitModuleImport(JCTree.java:3528) at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCModuleImport.accept(JCTree.java:720) at jdk.compiler/com.sun.tools.javac.tree.TreeInfo$DeclScanner.scan(TreeInfo.java:833) at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:58) at jdk.compiler/com.sun.tools.javac.tree.TreeScanner.visitTopLevel(TreeScanner.java:67) at jdk.compiler/com.sun.tools.javac.tree.TreeInfo$DeclScanner.visitTopLevel(TreeInfo.java:837) at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:553) at jdk.compiler/com.sun.tools.javac.tree.TreeInfo.declarationFor(TreeInfo.java:883) at jdk.compiler/com.sun.tools.javac.comp.Annotate.lambda$annotateLater$1(Annotate.java:279) at jdk.compiler/com.sun.tools.javac.comp.Annotate.flush(Annotate.java:200) at jdk.compiler/com.sun.tools.javac.comp.Annotate.unblockAnnotations(Annotate.java:144) at jdk.compiler/com.sun.tools.javac.comp.Annotate.enterDone(Annotate.java:157) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterDone(JavaCompiler.java:1813) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1079) at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:948) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100) at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94) at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92) at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94) at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57) at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:59) at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:41) at org.gradle.api.internal.tasks.compile.daemon.AbstractIsolatedCompilerWorkerExecutor$CompilerWorkAction.execute(AbstractIsolatedCompilerWorkerExecutor.java:78) at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63) at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54) at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48) at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100) at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48) at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:32) at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:22) at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:102) at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:71) at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:146) at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41) at org.gradle.process.internal.worker.request.WorkerAction.lambda$run$0(WorkerAction.java:143) at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80) at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:135) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164) at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1575) If this is known, please ignore. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Mon May 20 14:57:12 2024 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 20 May 2024 16:57:12 +0200 Subject: Module imports fail in a module-info.java file In-Reply-To: References: Message-ID: Hello Clayton, Thanks for the report. I believe this will be fixed as part of: https://bugs.openjdk.org/browse/JDK-8332497 Thanks, ??? Jan On 20. 05. 24 7:59, Clayton Walker wrote: > I tried adding a module import to the top of a module file and got a > compilation error. > > import module org.jspecify; > > @NullMarked > module org.example.mymodule { > ? ? requires org.jspecify; > } > > With the error > > An exception has occurred in the compiler (23-ea). Please file a bug > against the Java compiler via the Java bug reporting page > (https://bugreport.java.com) after checking the Bug Database > (https://bugs.java.com) for duplicates. Include your program, the > following diagnostic, and the parameters passed to the Java compiler > in your report. Thank you. > java.lang.AssertionError > at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155) > at > jdk.compiler/com.sun.tools.javac.tree.TreeScanner.visitTree(TreeScanner.java:415) > at > jdk.compiler/com.sun.tools.javac.tree.JCTree$Visitor.visitModuleImport(JCTree.java:3528) > at > jdk.compiler/com.sun.tools.javac.tree.JCTree$JCModuleImport.accept(JCTree.java:720) > at > jdk.compiler/com.sun.tools.javac.tree.TreeInfo$DeclScanner.scan(TreeInfo.java:833) > at > jdk.compiler/com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:58) > at > jdk.compiler/com.sun.tools.javac.tree.TreeScanner.visitTopLevel(TreeScanner.java:67) > at > jdk.compiler/com.sun.tools.javac.tree.TreeInfo$DeclScanner.visitTopLevel(TreeInfo.java:837) > at > jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:553) > at > jdk.compiler/com.sun.tools.javac.tree.TreeInfo.declarationFor(TreeInfo.java:883) > at > jdk.compiler/com.sun.tools.javac.comp.Annotate.lambda$annotateLater$1(Annotate.java:279) > at jdk.compiler/com.sun.tools.javac.comp.Annotate.flush(Annotate.java:200) > at > jdk.compiler/com.sun.tools.javac.comp.Annotate.unblockAnnotations(Annotate.java:144) > at > jdk.compiler/com.sun.tools.javac.comp.Annotate.enterDone(Annotate.java:157) > at > jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterDone(JavaCompiler.java:1813) > at > jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1079) > at > jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:948) > at > jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104) > at > jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152) > at > jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100) > at > jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94) > at > org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92) > at > org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94) > at > org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57) > at > org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:59) > at > org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:41) > at > org.gradle.api.internal.tasks.compile.daemon.AbstractIsolatedCompilerWorkerExecutor$CompilerWorkAction.execute(AbstractIsolatedCompilerWorkerExecutor.java:78) > at > org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63) > at > org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54) > at > org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48) > at > org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100) > at > org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48) > at > org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:32) > at > org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:22) > at > org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:102) > at > org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:71) > at > org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:146) > at > org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41) > at > org.gradle.process.internal.worker.request.WorkerAction.lambda$run$0(WorkerAction.java:143) > at > org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80) > at > org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:135) > at > java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) > at java.base/java.lang.reflect.Method.invoke(Method.java:580) > at > org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) > at > org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) > at > org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182) > at > org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164) > at > org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414) > at > org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) > at > org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47) > at > java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) > at > java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) > at java.base/java.lang.Thread.run(Thread.java:1575) > > If this is known, please ignore. > From ella.ananeva at oracle.com Mon May 20 21:12:55 2024 From: ella.ananeva at oracle.com (Ella Ananeva) Date: Mon, 20 May 2024 21:12:55 +0000 Subject: A possible bug in JEP 482: Flexible Constructor Bodies Message-ID: Hi, I found a discrepancy in the behavior of the JEP 482 compiler regarding definite assignment of a final non-static blank field in a prologue of a constructor: Case 1 Case 2 Case 3 class Q { final int x; int y; { y = x; } public Q(int a) { x = a; super(); } } class Q { final int x; int y; { y = x; } public Q(int a) { x = a; this(); } public Q() {} } class Q { final int x; int y; { y = x; } public Q(int a) { x = a; } } Compilation succeeds Compilation fails Compilation fails Shouldn?t the behavior in this 3 cases be similar? Thank you, Ella -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon May 20 21:43:04 2024 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 20 May 2024 23:43:04 +0200 (CEST) Subject: A possible bug in JEP 482: Flexible Constructor Bodies In-Reply-To: References: Message-ID: <1511527933.26686639.1716241384489.JavaMail.zimbra@univ-eiffel.fr> > From: "Ella Ananeva" > To: "amber-dev" > Sent: Monday, May 20, 2024 11:12:55 PM > Subject: A possible bug in JEP 482: Flexible Constructor Bodies > Hi, > I found a discrepancy in the behavior of the JEP 482 compiler regarding definite > assignment of a final non-static blank field in a prologue of a constructor: > Case 1 > Case 2 > Case 3 > class Q { > final int x ; > int y ; > { y = x ; } > public Q ( int a ) { > x = a ; > super (); > } > } > class Q { > final int x ; > int y ; > { y = x ; } > public Q ( int a ) { > x = a ; > this (); > } > public Q () {} > } > class Q { > final int x ; > int y ; > { y = x ; } > public Q ( int a ) { > x = a ; > } > } > Compilation succeeds > Compilation fails > Compilation fails > Shouldn?t the behavior in this 3 cases be similar? Hello, case 3 is equivalent to class Q { final int x ; int y ; public Q ( int a ) { y = x ; x = a ; } } so 'y' can not be initialized by 'x' given that 'x' is not initialized. case 1 is equivalent to class Q { final int x ; int y ; public Q ( int a ) { x = a ; super (); y = x ; } } so it compiles correctly, when y = x is executed, x is already initialized. For me, case 2 is a compiler bug, the call to this() is indirectly a super constructor call. > Thank you, > Ella regards, R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie.cobbs at gmail.com Mon May 20 22:00:51 2024 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Mon, 20 May 2024 17:00:51 -0500 Subject: A possible bug in JEP 482: Flexible Constructor Bodies In-Reply-To: References: Message-ID: Hi Ella, Thanks for the report. First, we can dispense with Case 3 - that program doesn't compile under any JDK version ("variable x might not have been initialized"), because initializer blocks run immediately after super(), which in this case is (implicitly) located at the beginning of the constructor and therefore prior to the assignment of x. Having said that, now take a look at Case 2: it has the same problem, but in a slightly different form. You can see this by trying to compile this version of Case 2 with the first constructor removed: class Q { final int x; int y; { y = x; } public Q() {} } You get the same error "variable x might not have been initialized". When you add back the first constructor to get your original Case 2, you still haven't fixed that problem. Then the compiler reports this: Q.java:7: error: variable x might already have been assigned this(); ^ Q.java:4: error: variable x might not have been initialized { y = x; } ^ The error reported on line 7 is slightly confusing, but it's really just a side effect of the error on line 4 that was already present. In other words, clearly someone could invoke the second constructor Q() and there would be nothing that initializes field x, so the program is not valid. On the other hand, the compiler assumes that the other constructor is going to properly initialize all final fields when it sees this(), and therefore it deduces that a duplicate assignment must be occurring. This assumption is wrong, but only because constructor Q() is invalid. Here's a version that does compile. Note that it fails if you uncomment the commented-out line. class Q { final int x; int y; { y = x; } public Q(int a) { //x = a; // "variable x might already have been assigned" this(); } public Q() { x = 3; super(); } } -Archie On Mon, May 20, 2024 at 4:13?PM Ella Ananeva wrote: > Hi, > > > > I found a discrepancy in the behavior of the JEP 482 compiler regarding > definite assignment of a final non-static blank field in a prologue of a > constructor: > > Case 1 > > Case 2 > > Case 3 > > class Q { > final int x; > int y; > { y = x; } > public Q(int a) { > x = a; > super(); > > } > } > > class Q { > final int x; > int y; > { y = x; } > public Q(int a) { > x = a; > this(); > } > > public Q() {} > } > > class Q { > final int x; > int y; > { y = x; } > public Q(int a) { > x = a; > } > } > > > > Compilation succeeds > > Compilation fails > > Compilation fails > > > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Mon May 20 23:19:59 2024 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 20 May 2024 16:19:59 -0700 Subject: A possible bug in JEP 482: Flexible Constructor Bodies In-Reply-To: References: Message-ID: <315ec0bb-6a76-4f09-99b0-2ee8f75853db@oracle.com> A. To restate in JCK terms: javac conforms to the spec in all three cases. - Case 1 is legal, and javac compiles it. - Case 2 is illegal, and javac does not compile it. It's illegal because the following new rule in 16.9 can't get x to be DA before the instance initializer: "V is definitely assigned (and moreover is not definitely unassigned) before the leftmost instance initializer (8.6) or instance variable initializer of C iff C declares at least one constructor, every constructor of C has an explicit constructor invocation, and V is definitely assigned after every superclass constructor invocation in these constructors." - Case 3 is illegal, and javac does not compile it. B. Because the new 16.9 rule speaks of "every constructor of C has an explicit constructor invocation", there should be a further test, 2a, which is the same as 2 but where the body of Q() is an explicit `super();`. (x would still not be DA after that `super();`.) C. JEP 482 introduces the notion of an "empty prologue": An explicit constructor invocation in a constructor body may be omitted. In this case the prologue is empty, and all the statements in the constructor body constitute the epilogue. and the draft JLS relies on the notion in 14.22 and 16.9 ... but AFAICT the notion isn't actually introduced in the draft JLS 8.8.7. Alex On 5/20/2024 3:00 PM, Archie Cobbs wrote: > Hi Ella, > > Thanks for the report. > > First, we can dispense with Case 3 - that program doesn't compile under > any JDK version ("variable x might not have been initialized"), because > initializer blocks run immediately after super(), which in this case is > (implicitly) located at the beginning of the constructor and therefore > prior to the assignment of x. > > Having said that, now take a look at Case 2: it has the same problem, > but in a slightly different form. > > You can see this by trying to compile this version of Case 2 with the > first constructor removed: > > class Q { > final int x; > int y; > ??? { y = x; } > public Q() {} > } > > > You get the same error "variable x might not have been initialized". > > > When you add back the first constructor to get your original Case 2, you > still haven't fixed that problem. > > > Then the compiler reports this: > > > Q.java:7: error: variable x might already have been assigned > ? ? ? ? this(); > ? ? ? ? ? ? ^ > Q.java:4: error: variable x might not have been initialized > ? ? { y = x; } > ? ? ? ? ? ^ > > > The error reported on line 7 is slightly confusing, but it's really just > a side effect of the error on line 4 that was already present. > > > In other words, clearly someone could invoke the second constructor Q() > and there would be nothing that initializes field x, so the program is > not valid. > > > On the other hand, the compiler assumes that the other constructor is > going to properly initialize all final fields when it sees this(), and > therefore it deduces that a duplicate assignment must be occurring. This > assumption is wrong, but only because constructor Q() is invalid. > > > Here's a version that does compile. Note that it fails if you uncomment > the commented-out line. > > > class Q { > ? ? final int x; > ? ? int y; > ? ? { y = x; } > ? ? public Q(int a) { > ? ? ? ? //x = a; ?? // "variable x might already have been assigned" > ? ? ? ? this(); > ? ? } > ? ? public Q() { > ? ? ? ? x = 3; > ? ? ? ? super(); > ? ? } > } > > > -Archie > > > On Mon, May 20, 2024 at 4:13?PM Ella Ananeva > wrote: > > Hi,____ > > __ __ > > I found a discrepancy in the behavior of the JEP 482 compiler > regarding definite assignment of a final non-static blank field in a > prologue of a constructor:____ > > Case 1____ > > > > Case 2____ > > > > Case 3____ > > class Q { > final int x; > int y; > ??? { y = x; } > public Q(int a) { > x = a; > super();____ > > ????} > }____ > > > > class Q { > final int x; > int y; > ??? { y = x; } > public Q(int a) { > x = a; > this(); > ??? }____ > > public Q() {} > }____ > > > > class Q { > final int x; > int y; > ??? { y = x; } > public Q(int a) { > x = a; > ????} > }____ > > __ __ > > Compilation succeeds____ > > > > Compilation fails____ > > > > Compilation fails____ > > __ > > > -- > Archie L. Cobbs From gavin.bierman at oracle.com Wed May 22 16:13:06 2024 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Wed, 22 May 2024 16:13:06 +0000 Subject: A possible bug in JEP 482: Flexible Constructor Bodies In-Reply-To: <315ec0bb-6a76-4f09-99b0-2ee8f75853db@oracle.com> References: <315ec0bb-6a76-4f09-99b0-2ee8f75853db@oracle.com> Message-ID: <2EC233C5-58F8-4D4E-95AB-3C69A5403252@oracle.com> Yes, thanks Alex. I will amend the draft JLS doc to explicitly state the possibility of empty prologue/epilogues. Gavin On 21 May 2024, at 00:19, Alex Buckley wrote: A. To restate in JCK terms: javac conforms to the spec in all three cases. - Case 1 is legal, and javac compiles it. - Case 2 is illegal, and javac does not compile it. It's illegal because the following new rule in 16.9 can't get x to be DA before the instance initializer: "V is definitely assigned (and moreover is not definitely unassigned) before the leftmost instance initializer (8.6) or instance variable initializer of C iff C declares at least one constructor, every constructor of C has an explicit constructor invocation, and V is definitely assigned after every superclass constructor invocation in these constructors." - Case 3 is illegal, and javac does not compile it. B. Because the new 16.9 rule speaks of "every constructor of C has an explicit constructor invocation", there should be a further test, 2a, which is the same as 2 but where the body of Q() is an explicit `super();`. (x would still not be DA after that `super();`.) C. JEP 482 introduces the notion of an "empty prologue": An explicit constructor invocation in a constructor body may be omitted. In this case the prologue is empty, and all the statements in the constructor body constitute the epilogue. and the draft JLS relies on the notion in 14.22 and 16.9 ... but AFAICT the notion isn't actually introduced in the draft JLS 8.8.7. Alex On 5/20/2024 3:00 PM, Archie Cobbs wrote: Hi Ella, Thanks for the report. First, we can dispense with Case 3 - that program doesn't compile under any JDK version ("variable x might not have been initialized"), because initializer blocks run immediately after super(), which in this case is (implicitly) located at the beginning of the constructor and therefore prior to the assignment of x. Having said that, now take a look at Case 2: it has the same problem, but in a slightly different form. You can see this by trying to compile this version of Case 2 with the first constructor removed: class Q { final int x; int y; { y = x; } public Q() {} } You get the same error "variable x might not have been initialized". When you add back the first constructor to get your original Case 2, you still haven't fixed that problem. Then the compiler reports this: Q.java:7: error: variable x might already have been assigned this(); ^ Q.java:4: error: variable x might not have been initialized { y = x; } ^ The error reported on line 7 is slightly confusing, but it's really just a side effect of the error on line 4 that was already present. In other words, clearly someone could invoke the second constructor Q() and there would be nothing that initializes field x, so the program is not valid. On the other hand, the compiler assumes that the other constructor is going to properly initialize all final fields when it sees this(), and therefore it deduces that a duplicate assignment must be occurring. This assumption is wrong, but only because constructor Q() is invalid. Here's a version that does compile. Note that it fails if you uncomment the commented-out line. class Q { final int x; int y; { y = x; } public Q(int a) { //x = a; // "variable x might already have been assigned" this(); } public Q() { x = 3; super(); } } -Archie On Mon, May 20, 2024 at 4:13?PM Ella Ananeva > wrote: Hi,____ __ __ I found a discrepancy in the behavior of the JEP 482 compiler regarding definite assignment of a final non-static blank field in a prologue of a constructor:____ Case 1____ Case 2____ Case 3____ class Q { final int x; int y; { y = x; } public Q(int a) { x = a; super();____ } }____ class Q { final int x; int y; { y = x; } public Q(int a) { x = a; this(); }____ public Q() {} }____ class Q { final int x; int y; { y = x; } public Q(int a) { x = a; } }____ __ __ Compilation succeeds____ Compilation fails____ Compilation fails____ __ -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From davidalayachew at gmail.com Mon May 27 21:03:59 2024 From: davidalayachew at gmail.com (David Alayachew) Date: Mon, 27 May 2024 17:03:59 -0400 Subject: Best Practices for New Language Feature Usage In-Reply-To: References: Message-ID: Most of the new syntax coming out has been as a result of Project Amber. So, adding them to this thread. On Mon, May 27, 2024 at 4:33?PM Nick Mancuso wrote: > Hello all, > > I maintain a static analysis tool for Java, called Checkstyle > . We do our best to stay up to > date with support for parsing the latest Java syntax, sometimes it is hard > to know what best practices are for a given feature, especially when it is > still in preview (we try to support high-demand preview features if they > have 2-3 preview releases). Would this mailing list be an appropriate place > to inquire about and discuss how to correctly (and incorrectly) use new > language features? > > For example, I was thinking of creating a post called "Java 21 Record > Pattern Best Practices". My hope would be that perhaps some of the folks > that worked on delivering, testing, or just using this feature could > comment on good usages, things they have seen that are a bad idea, and so > on. This would help Checkstyle immensely by inspiring the creation of new > ways to analyze code and help developers to use these new features in the > best possible way. > > Best, > Nick > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gstoyanov at live.com Wed May 29 11:58:03 2024 From: gstoyanov at live.com (Georgi Stoyanov) Date: Wed, 29 May 2024 11:58:03 +0000 Subject: Pattern matching improvements Message-ID: Hey folks, I'm really excited about the new Java features that keep getting added, and I had an idea I wanted to share. Have you thought about introducing a pattern matching feature similar to Scala?s, which allows for more concise and readable code? In Scala, you can match a list that starts with a specific element without having to spell everything out. For example: case List(_, 2, _*) => "I only care that this list has 2 as the second element" case Person("Alice", age) => "It's Alice" This approach makes the code less verbose and lets you focus directly on the elements you care about. It?s a lot cleaner than extracting elements and comparing them separately, which is what we do now in Java. I think adding something like this to Java would be a big win, making pattern matching more powerful and the code more readable. Just wanted to throw this idea out there and see what you all think. Kind Regards, Georgi Stoyanov -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed May 29 12:42:16 2024 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 29 May 2024 12:42:16 +0000 Subject: Pattern matching improvements In-Reply-To: References: Message-ID: We take inspiration from many sources, including many existing languages that have pattern matching. I think what you?re asking is: ?have you considered List patterns?. And indeed, we have. List patterns are the dual to list literals (more generally, collection patterns are the dual to collection literals); we would consider introducing collection patterns when we are able to treat them holistically with collection literals. However, of all the pattern matching features one could craft ?have you considered X? for, list patterns are among the weakest, and so these are likely to be lower priority than other pattern matching features in the pipeline (e.g., varargs patterns, constant patterns, etc.). On May 29, 2024, at 7:58 AM, Georgi Stoyanov > wrote: Hey folks, I'm really excited about the new Java features that keep getting added, and I had an idea I wanted to share. Have you thought about introducing a pattern matching feature similar to Scala?s, which allows for more concise and readable code? In Scala, you can match a list that starts with a specific element without having to spell everything out. For example: case List(_, 2, _*) => "I only care that this list has 2 as the second element" case Person("Alice", age) => "It's Alice" This approach makes the code less verbose and lets you focus directly on the elements you care about. It?s a lot cleaner than extracting elements and comparing them separately, which is what we do now in Java. I think adding something like this to Java would be a big win, making pattern matching more powerful and the code more readable. Just wanted to throw this idea out there and see what you all think. Kind Regards, Georgi Stoyanov -------------- next part -------------- An HTML attachment was scrubbed... URL: From rotanolexandr842 at gmail.com Wed May 29 13:12:30 2024 From: rotanolexandr842 at gmail.com (Olexandr Rotan) Date: Wed, 29 May 2024 16:12:30 +0300 Subject: Pattern matching improvements In-Reply-To: References: Message-ID: I would like to say that, imo, point that list (or any sequential collection/array) patterns make code readable is a really brave assumption to say the least. I had some experience reading code like this in C#, and to say that I was not impressed would be an understatement. For me, it gives off strong regex vibes, which are, meanwhile really powerful tool, known to be barely readable. Also example you have provided above seems kind of python-like in a way that in which situation would you expect List OR single object as input. Unless there are union types (which I'm also not a fan of to be fair), your example is not from the java world, in my opinion. The more realistic applixation for such patterns is match "shape" of collection, if you already know you are dealing with collection, but I'm not sure that game worth the candle to be fair. I guess such patterns could be more effective then traditional ways to do things that they are intended to substitute, so maybe in some caseslike data-oriented programming performance improvements could be significant, but besides I would think ten times before introducing another regex into the language. On Wed, May 29, 2024, 16:02 Brian Goetz wrote: > We take inspiration from many sources, including many existing languages > that have pattern matching. > > I think what you?re asking is: ?have you considered List patterns?. And > indeed, we have. List patterns are the dual to list literals (more > generally, collection patterns are the dual to collection literals); we > would consider introducing collection patterns when we are able to treat > them holistically with collection literals. However, of all the pattern > matching features one could craft ?have you considered X? for, list > patterns are among the weakest, and so these are likely to be lower > priority than other pattern matching features in the pipeline (e.g., > varargs patterns, constant patterns, etc.). > > On May 29, 2024, at 7:58 AM, Georgi Stoyanov wrote: > > Hey folks, > I'm really excited about the new Java features that keep getting added, > and I had an idea I wanted to share. Have you thought about introducing a > pattern matching feature similar to Scala?s, which allows for more concise > and readable code? > In Scala, you can match a list that starts with a specific element without > having to spell everything out. For example: > case List(_, 2, _*) => "I only care that this list has 2 as the second > element" > case Person("Alice", age) => "It's Alice" > > This approach makes the code less verbose and lets you focus directly on > the elements you care about. It?s a lot cleaner than extracting elements > and comparing them separately, which is what we do now in Java. > I think adding something like this to Java would be a big win, making > pattern matching more powerful and the code more readable. > Just wanted to throw this idea out there and see what you all think. > > Kind Regards, > Georgi Stoyanov > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed May 29 13:21:01 2024 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 29 May 2024 13:21:01 +0000 Subject: Pattern matching improvements In-Reply-To: References: Message-ID: <8F6F410B-B3F1-4288-BE2F-420E99729A53@oracle.com> Yes, these sorts of arguments are why I describe it as a weak candidate. One only needs to think about it for a minute or so to come up with a whole pile of ?follow on features? (?can I have a wildcard indicator that means any number of intervening elements?, ?can I have a way to express an element matching P comes before an element matching Q?, etc). List patterns are fundamental in languages where cons-lists (such as Lisp or Haskell) are a foundational data structure in the langauge. In that case, matching head/tail becomes a fundamental feature. But that?s not Java. On May 29, 2024, at 9:12 AM, Olexandr Rotan > wrote: I would like to say that, imo, point that list (or any sequential collection/array) patterns make code readable is a really brave assumption to say the least. I had some experience reading code like this in C#, and to say that I was not impressed would be an understatement. For me, it gives off strong regex vibes, which are, meanwhile really powerful tool, known to be barely readable. Also example you have provided above seems kind of python-like in a way that in which situation would you expect List OR single object as input. Unless there are union types (which I'm also not a fan of to be fair), your example is not from the java world, in my opinion. The more realistic applixation for such patterns is match "shape" of collection, if you already know you are dealing with collection, but I'm not sure that game worth the candle to be fair. I guess such patterns could be more effective then traditional ways to do things that they are intended to substitute, so maybe in some caseslike data-oriented programming performance improvements could be significant, but besides I would think ten times before introducing another regex into the language. On Wed, May 29, 2024, 16:02 Brian Goetz > wrote: We take inspiration from many sources, including many existing languages that have pattern matching. I think what you?re asking is: ?have you considered List patterns?. And indeed, we have. List patterns are the dual to list literals (more generally, collection patterns are the dual to collection literals); we would consider introducing collection patterns when we are able to treat them holistically with collection literals. However, of all the pattern matching features one could craft ?have you considered X? for, list patterns are among the weakest, and so these are likely to be lower priority than other pattern matching features in the pipeline (e.g., varargs patterns, constant patterns, etc.). On May 29, 2024, at 7:58 AM, Georgi Stoyanov > wrote: Hey folks, I'm really excited about the new Java features that keep getting added, and I had an idea I wanted to share. Have you thought about introducing a pattern matching feature similar to Scala?s, which allows for more concise and readable code? In Scala, you can match a list that starts with a specific element without having to spell everything out. For example: case List(_, 2, _*) => "I only care that this list has 2 as the second element" case Person("Alice", age) => "It's Alice" This approach makes the code less verbose and lets you focus directly on the elements you care about. It?s a lot cleaner than extracting elements and comparing them separately, which is what we do now in Java. I think adding something like this to Java would be a big win, making pattern matching more powerful and the code more readable. Just wanted to throw this idea out there and see what you all think. Kind Regards, Georgi Stoyanov -------------- next part -------------- An HTML attachment was scrubbed... URL: From gstoyanov at live.com Wed May 29 14:49:23 2024 From: gstoyanov at live.com (Georgi Stoyanov) Date: Wed, 29 May 2024 14:49:23 +0000 Subject: Pattern matching improvements In-Reply-To: <8F6F410B-B3F1-4288-BE2F-420E99729A53@oracle.com> References: <8F6F410B-B3F1-4288-BE2F-420E99729A53@oracle.com> Message-ID: Hi, thank you for the quick response! Yes, regarding the lists, it's indeed weak. But regarding actually the objects and matching them directly based on their values, without need to write something like case Person(name, age) where name == "Alice" && age == 40, but just case Person("Alice", 40) is really good feature, isn't it? Kind Regards, Georgi Stoyanov ________________________________ From: Brian Goetz Sent: Wednesday, May 29, 2024 4:21 PM To: Olexandr Rotan Cc: Georgi Stoyanov ; amber-dev at openjdk.org Subject: Re: Pattern matching improvements Yes, these sorts of arguments are why I describe it as a weak candidate. One only needs to think about it for a minute or so to come up with a whole pile of ?follow on features? (?can I have a wildcard indicator that means any number of intervening elements?, ?can I have a way to express an element matching P comes before an element matching Q?, etc). List patterns are fundamental in languages where cons-lists (such as Lisp or Haskell) are a foundational data structure in the langauge. In that case, matching head/tail becomes a fundamental feature. But that?s not Java. On May 29, 2024, at 9:12 AM, Olexandr Rotan > wrote: I would like to say that, imo, point that list (or any sequential collection/array) patterns make code readable is a really brave assumption to say the least. I had some experience reading code like this in C#, and to say that I was not impressed would be an understatement. For me, it gives off strong regex vibes, which are, meanwhile really powerful tool, known to be barely readable. Also example you have provided above seems kind of python-like in a way that in which situation would you expect List OR single object as input. Unless there are union types (which I'm also not a fan of to be fair), your example is not from the java world, in my opinion. The more realistic applixation for such patterns is match "shape" of collection, if you already know you are dealing with collection, but I'm not sure that game worth the candle to be fair. I guess such patterns could be more effective then traditional ways to do things that they are intended to substitute, so maybe in some caseslike data-oriented programming performance improvements could be significant, but besides I would think ten times before introducing another regex into the language. On Wed, May 29, 2024, 16:02 Brian Goetz > wrote: We take inspiration from many sources, including many existing languages that have pattern matching. I think what you?re asking is: ?have you considered List patterns?. And indeed, we have. List patterns are the dual to list literals (more generally, collection patterns are the dual to collection literals); we would consider introducing collection patterns when we are able to treat them holistically with collection literals. However, of all the pattern matching features one could craft ?have you considered X? for, list patterns are among the weakest, and so these are likely to be lower priority than other pattern matching features in the pipeline (e.g., varargs patterns, constant patterns, etc.). On May 29, 2024, at 7:58 AM, Georgi Stoyanov > wrote: Hey folks, I'm really excited about the new Java features that keep getting added, and I had an idea I wanted to share. Have you thought about introducing a pattern matching feature similar to Scala?s, which allows for more concise and readable code? In Scala, you can match a list that starts with a specific element without having to spell everything out. For example: case List(_, 2, _*) => "I only care that this list has 2 as the second element" case Person("Alice", age) => "It's Alice" This approach makes the code less verbose and lets you focus directly on the elements you care about. It?s a lot cleaner than extracting elements and comparing them separately, which is what we do now in Java. I think adding something like this to Java would be a big win, making pattern matching more powerful and the code more readable. Just wanted to throw this idea out there and see what you all think. Kind Regards, Georgi Stoyanov -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed May 29 14:54:59 2024 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 29 May 2024 14:54:59 +0000 Subject: Pattern matching improvements In-Reply-To: References: <8F6F410B-B3F1-4288-BE2F-420E99729A53@oracle.com> Message-ID: <06F9742D-250F-46FD-AFB9-DB195135E3CF@oracle.com> The feature you are talking about is ?constant patterns?, which is on the list. It involves using literals (strings, numbers) as patterns. On May 29, 2024, at 10:49 AM, Georgi Stoyanov > wrote: Hi, thank you for the quick response! Yes, regarding the lists, it's indeed weak. But regarding actually the objects and matching them directly based on their values, without need to write something like case Person(name, age) where name == "Alice" && age == 40, but just case Person("Alice", 40) is really good feature, isn't it? Kind Regards, Georgi Stoyanov ________________________________ From: Brian Goetz > Sent: Wednesday, May 29, 2024 4:21 PM To: Olexandr Rotan > Cc: Georgi Stoyanov >; amber-dev at openjdk.org > Subject: Re: Pattern matching improvements Yes, these sorts of arguments are why I describe it as a weak candidate. One only needs to think about it for a minute or so to come up with a whole pile of ?follow on features? (?can I have a wildcard indicator that means any number of intervening elements?, ?can I have a way to express an element matching P comes before an element matching Q?, etc). List patterns are fundamental in languages where cons-lists (such as Lisp or Haskell) are a foundational data structure in the langauge. In that case, matching head/tail becomes a fundamental feature. But that?s not Java. On May 29, 2024, at 9:12 AM, Olexandr Rotan > wrote: I would like to say that, imo, point that list (or any sequential collection/array) patterns make code readable is a really brave assumption to say the least. I had some experience reading code like this in C#, and to say that I was not impressed would be an understatement. For me, it gives off strong regex vibes, which are, meanwhile really powerful tool, known to be barely readable. Also example you have provided above seems kind of python-like in a way that in which situation would you expect List OR single object as input. Unless there are union types (which I'm also not a fan of to be fair), your example is not from the java world, in my opinion. The more realistic applixation for such patterns is match "shape" of collection, if you already know you are dealing with collection, but I'm not sure that game worth the candle to be fair. I guess such patterns could be more effective then traditional ways to do things that they are intended to substitute, so maybe in some caseslike data-oriented programming performance improvements could be significant, but besides I would think ten times before introducing another regex into the language. On Wed, May 29, 2024, 16:02 Brian Goetz > wrote: We take inspiration from many sources, including many existing languages that have pattern matching. I think what you?re asking is: ?have you considered List patterns?. And indeed, we have. List patterns are the dual to list literals (more generally, collection patterns are the dual to collection literals); we would consider introducing collection patterns when we are able to treat them holistically with collection literals. However, of all the pattern matching features one could craft ?have you considered X? for, list patterns are among the weakest, and so these are likely to be lower priority than other pattern matching features in the pipeline (e.g., varargs patterns, constant patterns, etc.). On May 29, 2024, at 7:58 AM, Georgi Stoyanov > wrote: Hey folks, I'm really excited about the new Java features that keep getting added, and I had an idea I wanted to share. Have you thought about introducing a pattern matching feature similar to Scala?s, which allows for more concise and readable code? In Scala, you can match a list that starts with a specific element without having to spell everything out. For example: case List(_, 2, _*) => "I only care that this list has 2 as the second element" case Person("Alice", age) => "It's Alice" This approach makes the code less verbose and lets you focus directly on the elements you care about. It?s a lot cleaner than extracting elements and comparing them separately, which is what we do now in Java. I think adding something like this to Java would be a big win, making pattern matching more powerful and the code more readable. Just wanted to throw this idea out there and see what you all think. Kind Regards, Georgi Stoyanov -------------- next part -------------- An HTML attachment was scrubbed... URL: From duke at openjdk.org Fri May 31 22:38:11 2024 From: duke at openjdk.org (duke) Date: Fri, 31 May 2024 22:38:11 GMT Subject: git: openjdk/amber: created branch pull/94 based on the branch master containing 58 unique commits Message-ID: <6021dd44-0d21-4b8a-a80d-88184d02d2ca@openjdk.org> The following commits are unique to the pull/94 branch: ======================================================== b30671fe: Compiler Implementation for Matchers e52fb18d: Multiple deconstructors, deconstructors for ordinary classes. 894e716f: Merge branch 'master' into matchers-experiment 448204ea: Group tests for matchers b208bed3: [WIP] Classreading bc48fbd8: Ability to read matchers. fb315418: Add preview feature ea9d32c0: Fix BoundMatcherAttribute 72dc3359: Add enable preview for two classfile tests affecting their jtreg @build command. 5fc5c3eb: Classreading member attributes df64e9c4: Merge branch 'master' into matchers-experiment a75af180: Merge branch 'master' into matchers-experiment 006b5999: Merge branch 'master' into matchers-experiment ccaa1ecf: Merge branch 'master' into matchers-experiment 0e23911b: Changes in Carrier (needs discussion) 385b813a: Overloading checkpoint f0813b01: Replace __matcher with the pattern keyword c9448f26: Pattern declarations in interfaces cf061303: Replace matcher with pattern declaration in type definitions and files afa23dcf: Add match statement 61cdde2e: Merge branch 'master' into matchers-experiment 76faa1e1: Address Stackmap bug 70d08494: Fix compilation of return of the carrier and throw MatchException in non total cases fe424a6e: Merge branch 'master' into matchers-experiment 2f6642b3: Clean up println 1ecb187c: Update JSONTest 5d29b7f4: Merge branch 'master' into matchers-experiment 0ae57239: Add more checks a8064a78: Cleanup d8704fd3: Merge branch 'master' into matchers-experiment fed074fc: Add test 4289ed33: Maintenance (javap, attributes, class-reading) ff726e42: Adding support for getDeclaredPatternDeclarations a0a99b3d: Add bytecode tests 0df5fc97: Retry for the windows test run 4ee2c0f8: Decouple params and bindings lists for pattern declaration methods 2e195354: Refactoring overloading of patterns and tests 3a574431: Merge branch 'refs/heads/master' into matchers-experiment 550b7cc4: Merge branch 'refs/heads/master' into matchers-experiment ebb803c7: Decouple bindings from parameters 4e5f96a7: Add synthetic parameter to pattern declarations 050aeb95: Add test for ExecutableElement.getBindings 52dbe205: Normalize javap output tests bf17e2f5: Merge branch 'refs/heads/master' into matchers-experiment 1f432812: Update after StringTemplates removal 42e8be76: Merge branch 'refs/heads/master' into matchers-experiment 82695a78: First draft of javax.lang.model changes 67f0100b: Address early review b29644ed: Rename to visitExecutableAsPatternDeclaration 48804d29: Fix imports f3dab7b7: Merge branch 'refs/heads/master' into matchers-experiment fc4585f0: Fix Whitespace errors bebb6af5: Merge branch 'refs/heads/master' into matchers-experiment d0275204: Add test for pattern declaration executable elements 7b693b4e: Fix annotation processing test with pattern declarations ccc44d4b: Detecting pattern attribute 936fe712: Rename to `getDeclaredDeconstructors` 06aa9176: minor change for test From duke at openjdk.org Fri May 31 22:54:28 2024 From: duke at openjdk.org (duke) Date: Fri, 31 May 2024 22:54:28 GMT Subject: git: openjdk/amber: created branch test based on the branch pull/94 containing 1 unique commit Message-ID: The following commits are unique to the test branch: ======================================================== 169bb744: test From duke at openjdk.org Fri May 31 22:56:11 2024 From: duke at openjdk.org (duke) Date: Fri, 31 May 2024 22:56:11 GMT Subject: git: openjdk/amber: pull/94: 2 new changesets Message-ID: <32d29bb5-2c5b-4f2d-992a-b55d59496787@openjdk.org> Changeset: 169bb744 Author: Vicente Romero Date: 2024-05-31 18:53:06 +0000 URL: https://git.openjdk.org/amber/commit/169bb7443bf49e9cf8452ad89d7a0cc739ccbab6 test ! src/java.compiler/share/classes/javax/lang/model/element/Modifier.java Changeset: 36fc7ac5 Author: Vicente Romero Zaldivar <62155190+vicente-romero-oracle at users.noreply.github.com> Committer: GitHub Date: 2024-05-31 18:54:43 +0000 URL: https://git.openjdk.org/amber/commit/36fc7ac5cea30cd21f7bbe481c3b2e9239e49ea0 Merge pull request #95 from openjdk/test test