From jlahoda at openjdk.java.net Thu Mar 4 13:19:06 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Thu, 4 Mar 2021 13:19:06 GMT Subject: RFR: 8253354: A jshell command to open desktop browser with specific javadoc query Message-ID: 8253354: A jshell command to open desktop browser with specific javadoc query ------------- Commit messages: - Updating copyright years. - Merge branch 'master' into JDK-8253355 - Cleanup. - Fixing tests. - Cleanup. - Cleanup. - Cleanup. - Cleanup whitespaces. - Cleanup, javadoc. - Cleanup. - ... and 1 more: https://git.openjdk.java.net/jdk/compare/94f26e4d...10ebfd02 Changes: https://git.openjdk.java.net/jdk/pull/2828/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=2828&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8253354 Stats: 623 lines in 9 files changed: 526 ins; 10 del; 87 mod Patch: https://git.openjdk.java.net/jdk/pull/2828.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/2828/head:pull/2828 PR: https://git.openjdk.java.net/jdk/pull/2828 From igraves at openjdk.java.net Fri Mar 12 21:56:12 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Fri, 12 Mar 2021 21:56:12 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() Message-ID: This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 ------------- Commit messages: - Converting jshell to use Stream.toList Changes: https://git.openjdk.java.net/jdk/pull/2979/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=2979&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8263411 Stats: 71 lines in 11 files changed: 3 ins; 12 del; 56 mod Patch: https://git.openjdk.java.net/jdk/pull/2979.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/2979/head:pull/2979 PR: https://git.openjdk.java.net/jdk/pull/2979 From smarks at openjdk.java.net Mon Mar 15 23:39:14 2021 From: smarks at openjdk.java.net (Stuart Marks) Date: Mon, 15 Mar 2021 23:39:14 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() In-Reply-To: References: Message-ID: <-ym-fDp-XQ0LaVzlS4KNQuc6q9lCpqSY9BUesGAHzhU=.273402a1-991e-4050-b877-7cc038e89d0a@github.com> On Fri, 12 Mar 2021 21:51:07 GMT, Ian Graves wrote: > This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. > > This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java line 177: > 175: .map(isi -> isi.fullname.substring(0, isi.fullname.lastIndexOf("."))); > 176: pkgs = Stream.concat(Stream.of("java.lang"), pkgs); > 177: for (String ipkg : pkgs.toList()) { The original code is strictly speaking in error, as it's modifying the list returned from `Collectors.toList()` which is not guaranteed to be mutable. (Obviously, this isn't enforced.) Instead of concatenating the element to the head of the stream and using `Stream.toList()`, though, it might be just as easy to convert the original code to use `collect(Collectors.toCollection(ArrayList::new))` and leave the insertion of "java.lang" at the front at before. Might make things clearer as to what's going on. (A slight variation would be to static-import j.u.s.Collectors.toCollection.) I'll defer to the jshell team on their preference here. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From jlahoda at openjdk.java.net Tue Mar 16 08:25:25 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Tue, 16 Mar 2021 08:25:25 GMT Subject: RFR: 8259863: doc: JShell snippet doesn't compile Message-ID: Fixing the snippet in `src/jdk.jshell/share/classes/jdk/jshell/package-info.java` so that it compiles. ------------- Commit messages: - 8259863: doc: JShell snippet doesn't compile Changes: https://git.openjdk.java.net/jdk/pull/3023/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3023&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8259863 Stats: 7 lines in 1 file changed: 0 ins; 0 del; 7 mod Patch: https://git.openjdk.java.net/jdk/pull/3023.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3023/head:pull/3023 PR: https://git.openjdk.java.net/jdk/pull/3023 From sundar at openjdk.java.net Wed Mar 17 08:58:20 2021 From: sundar at openjdk.java.net (Athijegannathan Sundararajan) Date: Wed, 17 Mar 2021 08:58:20 GMT Subject: RFR: 8259863: doc: JShell snippet doesn't compile In-Reply-To: References: Message-ID: <7dJnrxN-llJ0XaQ0t7u8g2RcbHUHPIZIUqn-v4xIG6A=.21563eb9-dc1c-4983-936e-ac452a833ced@github.com> On Tue, 16 Mar 2021 08:19:28 GMT, Jan Lahoda wrote: > Fixing the snippet in `src/jdk.jshell/share/classes/jdk/jshell/package-info.java` so that it compiles. Marked as reviewed by sundar (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/3023 From jlahoda at openjdk.java.net Wed Mar 17 12:39:55 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Wed, 17 Mar 2021 12:39:55 GMT Subject: Integrated: 8259863: doc: JShell snippet doesn't compile In-Reply-To: References: Message-ID: On Tue, 16 Mar 2021 08:19:28 GMT, Jan Lahoda wrote: > Fixing the snippet in `src/jdk.jshell/share/classes/jdk/jshell/package-info.java` so that it compiles. This pull request has now been integrated. Changeset: 41276eb8 Author: Jan Lahoda URL: https://git.openjdk.java.net/jdk/commit/41276eb8 Stats: 7 lines in 1 file changed: 0 ins; 0 del; 7 mod 8259863: doc: JShell snippet doesn't compile Reviewed-by: sundar ------------- PR: https://git.openjdk.java.net/jdk/pull/3023 From jlahoda at openjdk.java.net Thu Mar 18 20:27:39 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Thu, 18 Mar 2021 20:27:39 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() In-Reply-To: References: Message-ID: On Fri, 12 Mar 2021 21:51:07 GMT, Ian Graves wrote: > This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. > > This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 Overall looks good to me. Please see two comments inline. src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java line 600: > 598: .map(Suggestion::continuation) > 599: .distinct() > 600: .map(s -> (CharSequence) s) This may be a personal preference, but I am not particularly happy about these casts (here and on other places). I'd rather: -change the target type, if possible, so that the cast would not be necessary; in this case, changing `toShow` to `List toShow;` should work, and similar changes may work in other cases as well; that should make things clearer, I think. (And the `List` will be effectively unmodifiable by type, not only at runtime.) -keep the `collect(toList())` ------------- Marked as reviewed by jlahoda (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/2979 From jlahoda at openjdk.java.net Thu Mar 18 20:27:41 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Thu, 18 Mar 2021 20:27:41 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() In-Reply-To: <-ym-fDp-XQ0LaVzlS4KNQuc6q9lCpqSY9BUesGAHzhU=.273402a1-991e-4050-b877-7cc038e89d0a@github.com> References: <-ym-fDp-XQ0LaVzlS4KNQuc6q9lCpqSY9BUesGAHzhU=.273402a1-991e-4050-b877-7cc038e89d0a@github.com> Message-ID: On Mon, 15 Mar 2021 23:35:14 GMT, Stuart Marks wrote: >> This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. >> >> This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 > > src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java line 177: > >> 175: .map(isi -> isi.fullname.substring(0, isi.fullname.lastIndexOf("."))); >> 176: pkgs = Stream.concat(Stream.of("java.lang"), pkgs); >> 177: for (String ipkg : pkgs.toList()) { > > The original code is strictly speaking in error, as it's modifying the list returned from `Collectors.toList()` which is not guaranteed to be mutable. (Obviously, this isn't enforced.) Instead of concatenating the element to the head of the stream and using `Stream.toList()`, though, it might be just as easy to convert the original code to use `collect(Collectors.toCollection(ArrayList::new))` and leave the insertion of "java.lang" at the front at before. Might make things clearer as to what's going on. > > (A slight variation would be to static-import j.u.s.Collectors.toCollection.) > > I'll defer to the jshell team on their preference here. If I was writing this, I'd probably go with `collect(Collectors.toCollection(ArrayList::new))`, but I don't see the `concat` as too bad. When using `concat`, another idea would be to avoid the `.toList()`, and re-write the loop to Streams completely. After all, it seems to be something along the lines of: Stream pkgs = importSnippets() .filter(isi -> isi.isStar) .map(isi -> isi.fullname.substring(0, isi.fullname.lastIndexOf("."))); return Stream.concat(Stream.of("java.lang"), pkgs) .filter(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) .map(ipkg -> full.substring(pkg.length() + 1)) .findFirst() .orElse(full); ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From github.com+828220+forax at openjdk.java.net Thu Mar 18 20:44:39 2021 From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax) Date: Thu, 18 Mar 2021 20:44:39 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() In-Reply-To: References: Message-ID: On Thu, 18 Mar 2021 20:16:31 GMT, Jan Lahoda wrote: > that should make things clearer, I think. (And the `List` will be effectively unmodifiable by type, not only at runtime.) Jan, don't forget that you can always do a `add(null)` or `clear()` on a List, so there is no way in Java to specify an unmodifiable type for a java.util.List. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Thu Mar 18 22:25:51 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Thu, 18 Mar 2021 22:25:51 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v2] In-Reply-To: References: Message-ID: > This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. > > This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 Ian Graves has updated the pull request incrementally with one additional commit since the last revision: Removing most explicit casts and refactoring a Stream use ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/2979/files - new: https://git.openjdk.java.net/jdk/pull/2979/files/bf0f3cfb..fd520aa0 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=2979&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=2979&range=00-01 Stats: 14 lines in 3 files changed: 0 ins; 4 del; 10 mod Patch: https://git.openjdk.java.net/jdk/pull/2979.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/2979/head:pull/2979 PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Thu Mar 18 22:25:51 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Thu, 18 Mar 2021 22:25:51 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v2] In-Reply-To: References: Message-ID: On Thu, 18 Mar 2021 20:25:14 GMT, Jan Lahoda wrote: >> Ian Graves has updated the pull request incrementally with one additional commit since the last revision: >> >> Removing most explicit casts and refactoring a Stream use > > Overall looks good to me. Please see two comments inline. Updated mostly in line with @lahodaj 's suggestions. I removed one explicit map-cast and replaced it with an explicit type argument to guide the type checker to the right widening. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Thu Mar 18 22:25:52 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Thu, 18 Mar 2021 22:25:52 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v2] In-Reply-To: References: Message-ID: On Thu, 18 Mar 2021 20:41:16 GMT, R?mi Forax wrote: >> src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java line 600: >> >>> 598: .map(Suggestion::continuation) >>> 599: .distinct() >>> 600: .map(s -> (CharSequence) s) >> >> This may be a personal preference, but I am not particularly happy about these casts (here and on other places). I'd rather: >> -change the target type, if possible, so that the cast would not be necessary; in this case, changing `toShow` to `List toShow;` should work, and similar changes may work in other cases as well; that should make things clearer, I think. (And the `List` will be effectively unmodifiable by type, not only at runtime.) >> -keep the `collect(toList())` > >> that should make things clearer, I think. (And the `List` will be effectively unmodifiable by type, not only at runtime.) > > Jan, > don't forget that you can always do a `add(null)` or `clear()` on a List, so there is no way in Java to specify an unmodifiable type for a java.util.List. Updated to match the suggestions RE the `toShow` assignments. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From jlahoda at openjdk.java.net Tue Mar 23 13:03:04 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Tue, 23 Mar 2021 13:03:04 GMT Subject: RFR: 8254196: jshell infinite loops when startup script contains System.exit call Message-ID: If the startup script contains `System.exit(0);`, JShell will end up in an infinite loop of remote agent crashing, restarting, startup script running on the new instance, crashing, etc. The proposal here is to avoid re-running the script from the beginning after the remote stops during startup. This should be fairly consistent with behavior of options like "/reload". Behavior in other cases should be unmodified. ------------- Commit messages: - 8254196: jshell infinite loops when startup script contains System.exit call Changes: https://git.openjdk.java.net/jdk/pull/3150/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3150&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8254196 Stats: 27 lines in 3 files changed: 24 ins; 0 del; 3 mod Patch: https://git.openjdk.java.net/jdk/pull/3150.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3150/head:pull/3150 PR: https://git.openjdk.java.net/jdk/pull/3150 From sundar at openjdk.java.net Tue Mar 23 13:16:41 2021 From: sundar at openjdk.java.net (Athijegannathan Sundararajan) Date: Tue, 23 Mar 2021 13:16:41 GMT Subject: RFR: 8254196: jshell infinite loops when startup script contains System.exit call In-Reply-To: References: Message-ID: On Tue, 23 Mar 2021 12:57:40 GMT, Jan Lahoda wrote: > If the startup script contains `System.exit(0);`, JShell will end up in an infinite loop of remote agent crashing, restarting, startup script running on the new instance, crashing, etc. > > The proposal here is to avoid re-running the script from the beginning after the remote stops during startup. This should be fairly consistent with behavior of options like "/reload". Behavior in other cases should be unmodified. Marked as reviewed by sundar (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/3150 From igraves at openjdk.java.net Tue Mar 23 14:57:40 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Tue, 23 Mar 2021 14:57:40 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v2] In-Reply-To: References: Message-ID: On Thu, 18 Mar 2021 20:25:14 GMT, Jan Lahoda wrote: >> Ian Graves has updated the pull request incrementally with one additional commit since the last revision: >> >> Removing most explicit casts and refactoring a Stream use > > Overall looks good to me. Please see two comments inline. @lahodaj if you're good with these changes I can go ahead and integrate so you can sponsor. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From jlahoda at openjdk.java.net Tue Mar 23 16:43:43 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Tue, 23 Mar 2021 16:43:43 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v2] In-Reply-To: References: Message-ID: <5uBQjZ_Vphie8wvXse6vAzD2VVefwh3yNokLeYMjPdg=.f779588a-7a95-46e2-a83e-cc73d9894228@github.com> On Thu, 18 Mar 2021 22:25:51 GMT, Ian Graves wrote: >> This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. >> >> This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 > > Ian Graves has updated the pull request incrementally with one additional commit since the last revision: > > Removing most explicit casts and refactoring a Stream use src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java line 1689: > 1687: } > 1688: }) > 1689: .map(e -> (Suggestion) e) I guess I'd get rid of the cast here as well. Otherwise looks good! ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Tue Mar 23 16:59:57 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Tue, 23 Mar 2021 16:59:57 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v3] In-Reply-To: References: Message-ID: > This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. > > This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 Ian Graves has updated the pull request incrementally with one additional commit since the last revision: Fixing a forgotten cast ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/2979/files - new: https://git.openjdk.java.net/jdk/pull/2979/files/fd520aa0..9fe5634f Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=2979&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=2979&range=01-02 Stats: 2 lines in 1 file changed: 0 ins; 1 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/2979.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/2979/head:pull/2979 PR: https://git.openjdk.java.net/jdk/pull/2979 From jlahoda at openjdk.java.net Tue Mar 23 17:11:40 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Tue, 23 Mar 2021 17:11:40 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v3] In-Reply-To: References: Message-ID: On Tue, 23 Mar 2021 14:54:46 GMT, Ian Graves wrote: >> Overall looks good to me. Please see two comments inline. > > @lahodaj if you're good with these changes I can go ahead and integrate so you can sponsor. Looks good! ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Tue Mar 23 17:11:41 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Tue, 23 Mar 2021 17:11:41 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v2] In-Reply-To: <5uBQjZ_Vphie8wvXse6vAzD2VVefwh3yNokLeYMjPdg=.f779588a-7a95-46e2-a83e-cc73d9894228@github.com> References: <5uBQjZ_Vphie8wvXse6vAzD2VVefwh3yNokLeYMjPdg=.f779588a-7a95-46e2-a83e-cc73d9894228@github.com> Message-ID: On Tue, 23 Mar 2021 16:40:57 GMT, Jan Lahoda wrote: >> Ian Graves has updated the pull request incrementally with one additional commit since the last revision: >> >> Removing most explicit casts and refactoring a Stream use > > src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java line 1689: > >> 1687: } >> 1688: }) >> 1689: .map(e -> (Suggestion) e) > > I guess I'd get rid of the cast here as well. Otherwise looks good! Ah yes, missed that one. Done! ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Wed Mar 24 09:34:41 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Wed, 24 Mar 2021 09:34:41 GMT Subject: Integrated: JDK-8263411: Convert jshell tool to use Stream.toList() In-Reply-To: References: Message-ID: On Fri, 12 Mar 2021 21:51:07 GMT, Ian Graves wrote: > This converts jshell from using `Stream.collect(Collectiors.toList())` to `Stream.toList()` - an immutable list with better performance characteristics. Local inspection only turned up one place that was mutating a resulting list and that has been refactored. > > This work is a subtask to: https://bugs.openjdk.java.net/browse/JDK-8260559 This pull request has now been integrated. Changeset: fad84840 Author: Ian Graves Committer: Jan Lahoda URL: https://git.openjdk.java.net/jdk/commit/fad84840 Stats: 74 lines in 11 files changed: 0 ins; 14 del; 60 mod 8263411: Convert jshell tool to use Stream.toList() Reviewed-by: jlahoda ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From jlahoda at openjdk.java.net Wed Mar 24 10:37:40 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Wed, 24 Mar 2021 10:37:40 GMT Subject: Integrated: 8254196: jshell infinite loops when startup script contains System.exit call In-Reply-To: References: Message-ID: On Tue, 23 Mar 2021 12:57:40 GMT, Jan Lahoda wrote: > If the startup script contains `System.exit(0);`, JShell will end up in an infinite loop of remote agent crashing, restarting, startup script running on the new instance, crashing, etc. > > The proposal here is to avoid re-running the script from the beginning after the remote stops during startup. This should be fairly consistent with behavior of options like "/reload". Behavior in other cases should be unmodified. This pull request has now been integrated. Changeset: 6c0fbf70 Author: Jan Lahoda URL: https://git.openjdk.java.net/jdk/commit/6c0fbf70 Stats: 27 lines in 3 files changed: 24 ins; 0 del; 3 mod 8254196: jshell infinite loops when startup script contains System.exit call Reviewed-by: sundar ------------- PR: https://git.openjdk.java.net/jdk/pull/3150 From jlahoda at openjdk.java.net Wed Mar 24 11:48:54 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Wed, 24 Mar 2021 11:48:54 GMT Subject: RFR: 8238173: jshell - switch statement with a single default not return cause syntax error Message-ID: Improving disambiguation between switch expressions and switch statements: switches that do not yield a value from any arm should not be considered switch expressions; switches in source levels that don't support switch expressions should always be considered switch statements. ------------- Commit messages: - 8238173: jshell - switch statement with a single default not return cause syntax error Changes: https://git.openjdk.java.net/jdk/pull/3173/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3173&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8238173 Stats: 56 lines in 5 files changed: 32 ins; 22 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/3173.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3173/head:pull/3173 PR: https://git.openjdk.java.net/jdk/pull/3173 From tvaleev at openjdk.java.net Thu Mar 25 08:43:41 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Thu, 25 Mar 2021 08:43:41 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v3] In-Reply-To: References: Message-ID: On Tue, 23 Mar 2021 17:08:53 GMT, Jan Lahoda wrote: >> @lahodaj if you're good with these changes I can go ahead and integrate so you can sponsor. > > Looks good! Sorry to be late but the change in SnippetMaps.java looks really confusing to me: return Stream.concat(Stream.of("java.lang"), pkgs) .filter(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) .map(ipkg -> full.substring(pkg.length() + 1)) .findFirst() .orElse(full); The elements in the stream after `map` do not depend on the previous stream content. To me, it looks a misuse of stream API. Here, `anyMatch` scenario would look better: return Stream.concat(Stream.of("java.lang"), pkgs) .anyMatch(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) ? full.substring(pkg.length() + 1) : full; Also, it looks like the emptiness check could be applied to `pkg` variable, rather than to every stream element (as we require equality of `ipkg` and `pkg` after that: return !pkg.isEmpty() && Stream.concat(Stream.of("java.lang"), pkgs).anyMatch(pkg::equals) ? full.substring(pkg.length() + 1) : full; Sorry if I'm missing something. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From igraves at openjdk.java.net Thu Mar 25 14:47:25 2021 From: igraves at openjdk.java.net (Ian Graves) Date: Thu, 25 Mar 2021 14:47:25 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v3] In-Reply-To: References: Message-ID: On Thu, 25 Mar 2021 08:40:37 GMT, Tagir F. Valeev wrote: >> Looks good! > > Sorry to be late but the change in SnippetMaps.java looks really confusing to me: > > return Stream.concat(Stream.of("java.lang"), pkgs) > .filter(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) > .map(ipkg -> full.substring(pkg.length() + 1)) > .findFirst() > .orElse(full); > The elements in the stream after `map` do not depend on the previous stream content. To me, it looks a misuse of stream API. Here, `anyMatch` scenario would look better: > return Stream.concat(Stream.of("java.lang"), pkgs) > .anyMatch(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) > ? full.substring(pkg.length() + 1) : full; > > Also, it looks like the emptiness check could be applied to `pkg` variable, rather than to every stream element (as we require equality of `ipkg` and `pkg` after that: > > return !pkg.isEmpty() && Stream.concat(Stream.of("java.lang"), pkgs).anyMatch(pkg::equals) > ? full.substring(pkg.length() + 1) : full; > > Sorry if I'm missing something. @amaembo Since the issue is now closed and these suggestions don't have to do with correctness, I'd suggest creating a new issue and PR to put these proposed improvements forward. Thanks! ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From tvaleev at openjdk.java.net Fri Mar 26 00:26:24 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Fri, 26 Mar 2021 00:26:24 GMT Subject: RFR: JDK-8263411: Convert jshell tool to use Stream.toList() [v3] In-Reply-To: References: Message-ID: On Thu, 25 Mar 2021 14:44:19 GMT, Ian Graves wrote: >> Sorry to be late but the change in SnippetMaps.java looks really confusing to me: >> >> return Stream.concat(Stream.of("java.lang"), pkgs) >> .filter(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) >> .map(ipkg -> full.substring(pkg.length() + 1)) >> .findFirst() >> .orElse(full); >> The elements in the stream after `map` do not depend on the previous stream content. To me, it looks a misuse of stream API. Here, `anyMatch` scenario would look better: >> return Stream.concat(Stream.of("java.lang"), pkgs) >> .anyMatch(ipkg -> !ipkg.isEmpty() && ipkg.equals(pkg)) >> ? full.substring(pkg.length() + 1) : full; >> >> Also, it looks like the emptiness check could be applied to `pkg` variable, rather than to every stream element (as we require equality of `ipkg` and `pkg` after that: >> >> return !pkg.isEmpty() && Stream.concat(Stream.of("java.lang"), pkgs).anyMatch(pkg::equals) >> ? full.substring(pkg.length() + 1) : full; >> >> Sorry if I'm missing something. > > @amaembo Since the issue is now closed and these suggestions don't have to do with correctness, I'd suggest creating a new issue and PR to put these proposed improvements forward. Thanks! @igraves thanks, filed: https://bugs.openjdk.java.net/browse/JDK-8264221. I'm not sure about type and tags. ------------- PR: https://git.openjdk.java.net/jdk/pull/2979 From tvaleev at openjdk.java.net Fri Mar 26 00:33:32 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Fri, 26 Mar 2021 00:33:32 GMT Subject: RFR: JDK-8264221: Rewrite confusing stream API chain in SnippetMaps Message-ID: I also simplified a couple of other places: replaced `stream().forEach()` with just `forEach()` and removed redundant `length()` argument in `substring()` call. ------------- Commit messages: - SnippetMaps updated Changes: https://git.openjdk.java.net/jdk/pull/3209/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3209&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8264221 Stats: 12 lines in 1 file changed: 3 ins; 3 del; 6 mod Patch: https://git.openjdk.java.net/jdk/pull/3209.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3209/head:pull/3209 PR: https://git.openjdk.java.net/jdk/pull/3209 From tvaleev at openjdk.java.net Fri Mar 26 00:49:31 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Fri, 26 Mar 2021 00:49:31 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible Message-ID: This change is powered by IntelliJ IDEA quick-fix. I also took the liberty to fix C-style arrays in changed files. In SourceCodeAnalysisImpl.java:501, I left case PARAMETERIZED_TYPE -> FALSE as a separate switch case, because it had a comment. Better formatting ideas are welcome. If you like this, I can provide similar PR in other components as well (e.g. in javac) ------------- Commit messages: - Use switch expression where possible Changes: https://git.openjdk.java.net/jdk/pull/3210/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3210&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8264222 Stats: 139 lines in 5 files changed: 0 ins; 78 del; 61 mod Patch: https://git.openjdk.java.net/jdk/pull/3210.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3210/head:pull/3210 PR: https://git.openjdk.java.net/jdk/pull/3210 From jlahoda at openjdk.java.net Fri Mar 26 16:50:41 2021 From: jlahoda at openjdk.java.net (Jan Lahoda) Date: Fri, 26 Mar 2021 16:50:41 GMT Subject: RFR: 8255273: jshell crashes with UnsupportedOperationException: Should not get here. Message-ID: Consider JShell interaction like: jshell> import java.time.*; jshell> new Instant This will crash the JShell with an `UnsupportedOperationException`. The ultimately reason is that: -completions are computed, and are `InstantiationError(` and `InstantiationException(`, with a common prefix `InstantiationE` -documentation is computed, and is for java.time.Instant The completion state machine then gets into a state where it fills in the common prefix, and then it would like say something along the lines of "Press tab once more to see signature/documentation.", but that does not make much sense (as the documentation is computed for a wrong input - the new input is `new InstantiationE`, not `Instant`, so the documentation is already invalid for that. (The `UnsupportedOperationException` is in place where the "Press tab once more to see signature/documentation." should happen, because the code should not get into a state like this.) The proposed solution is to cancel the documentation if a prefix is (to be) filled. ------------- Commit messages: - Fixing compilation error. - Merging master into JDK-8255273 - 8255273: jshell crashes with UnsupportedOperationException: Should not get here. Changes: https://git.openjdk.java.net/jdk/pull/3220/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3220&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8255273 Stats: 101 lines in 2 files changed: 60 ins; 27 del; 14 mod Patch: https://git.openjdk.java.net/jdk/pull/3220.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3220/head:pull/3220 PR: https://git.openjdk.java.net/jdk/pull/3220 From briangoetz at openjdk.java.net Fri Mar 26 22:10:24 2021 From: briangoetz at openjdk.java.net (Brian Goetz) Date: Fri, 26 Mar 2021 22:10:24 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible In-Reply-To: References: Message-ID: On Fri, 26 Mar 2021 00:43:44 GMT, Tagir F. Valeev wrote: > This change is powered by IntelliJ IDEA quick-fix. > I also took the liberty to fix C-style arrays in changed files. > > In SourceCodeAnalysisImpl.java:501, I left case PARAMETERIZED_TYPE -> FALSE as a separate switch case, because it had a comment. Better formatting ideas are welcome. > > If you like this, I can provide similar PR in other components as well (e.g. in javac) Cute trick for the partial update to `c`. The comment in the last hunk (resultTypeOf()) only applied to the INSTANCE and STATIC init cases, but now it applies to CONSTRUCTOR too (in a previous hunk, you deliberately had a redundant case, to preserve this information.) I would update the comment. Otherwise, all looks good to me, +1. ------------- Marked as reviewed by briangoetz (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/3210 From tvaleev at openjdk.java.net Fri Mar 26 23:47:41 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Fri, 26 Mar 2021 23:47:41 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: Message-ID: > This change is powered by IntelliJ IDEA quick-fix. > I also took the liberty to fix C-style arrays in changed files. > > In SourceCodeAnalysisImpl.java:501, I left case PARAMETERIZED_TYPE -> FALSE as a separate switch case, because it had a comment. Better formatting ideas are welcome. > > If you like this, I can provide similar PR in other components as well (e.g. in javac) Tagir F. Valeev has updated the pull request incrementally with two additional commits since the last revision: - resultTypeOf: update comment instead of splitting the case - resultTypeOf: split CONSTRUCTOR and INSTANCE_INIT/STATIC_INIT case to position the comments properly ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/3210/files - new: https://git.openjdk.java.net/jdk/pull/3210/files/4cd18d8e..a6501a96 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=3210&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=3210&range=00-01 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/3210.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3210/head:pull/3210 PR: https://git.openjdk.java.net/jdk/pull/3210 From tvaleev at openjdk.java.net Fri Mar 26 23:50:24 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Fri, 26 Mar 2021 23:50:24 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: Message-ID: On Fri, 26 Mar 2021 22:07:22 GMT, Brian Goetz wrote: >> Tagir F. Valeev has updated the pull request incrementally with two additional commits since the last revision: >> >> - resultTypeOf: update comment instead of splitting the case >> - resultTypeOf: split CONSTRUCTOR and INSTANCE_INIT/STATIC_INIT case to position the comments properly > > Cute trick for the partial update to `c`. > The comment in the last hunk (resultTypeOf()) only applied to the INSTANCE and STATIC init cases, but now it applies to CONSTRUCTOR too (in a previous hunk, you deliberately had a redundant case, to preserve this information.) I would update the comment. > > Otherwise, all looks good to me, +1. @briangoetz thank you for review! > I would update the comment. I updated the comment and moved it before the case branch. Please take a look. > Cute trick for the partial update to c. Yeah, IDEA does this automatically! ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From briangoetz at openjdk.java.net Sat Mar 27 00:34:25 2021 From: briangoetz at openjdk.java.net (Brian Goetz) Date: Sat, 27 Mar 2021 00:34:25 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: Message-ID: On Fri, 26 Mar 2021 23:47:41 GMT, Tagir F. Valeev wrote: >> This change is powered by IntelliJ IDEA quick-fix. >> I also took the liberty to fix C-style arrays in changed files. >> >> In SourceCodeAnalysisImpl.java:501, I left case PARAMETERIZED_TYPE -> FALSE as a separate switch case, because it had a comment. Better formatting ideas are welcome. >> >> If you like this, I can provide similar PR in other components as well (e.g. in javac) > > Tagir F. Valeev has updated the pull request incrementally with two additional commits since the last revision: > > - resultTypeOf: update comment instead of splitting the case > - resultTypeOf: split CONSTRUCTOR and INSTANCE_INIT/STATIC_INIT case to position the comments properly Marked as reviewed by briangoetz (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From smarks at openjdk.java.net Sat Mar 27 00:42:24 2021 From: smarks at openjdk.java.net (Stuart Marks) Date: Sat, 27 Mar 2021 00:42:24 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: Message-ID: On Sat, 27 Mar 2021 00:31:30 GMT, Brian Goetz wrote: >> Tagir F. Valeev has updated the pull request incrementally with two additional commits since the last revision: >> >> - resultTypeOf: update comment instead of splitting the case >> - resultTypeOf: split CONSTRUCTOR and INSTANCE_INIT/STATIC_INIT case to position the comments properly > > Marked as reviewed by briangoetz (Reviewer). I have some formatting questions. I also have some weak opinions on formatting, but not strong enough to make recommendations yet. (I see you wrote "Better formatting ideas are welcome" so thanks for being open to this.) I'm interested in feedback on how the code ends up _reading_, particularly from the people who will be maintaining this code. But comments from others are welcome too. The switch (c) in `ArgTokenizer::nextToken` is pretty nicely formatted, since each case has a single constant, they're all short, and the values are also all constants that are textually short. The only thing I'd say here is to add a bit of spacing to the default case so that the arrows line up. In `Eval::prettyExpr` switch (typeName), the switch is a bit irregular since one of the case arms has multiple constants. This makes it a bit harder to find one if you're looking for it in particular. For example, suppose you want to find out how "int" is handled. In the old code you can scan down looking at each `case` and then look at the constant right next to it. In the new code (as modified) the "int" is farther away from the `case` keyword and is a bit lost among the values, so it's harder to see. Let me see how the variations look. Here's the modified version as proposed in the PR: String sinit = switch (typeName) { case "byte", "short", "int" -> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default -> "null"; }; Variation with the arrows on the same line, but lined up: String sinit = switch (typeName) { case "byte", "short", "int" -> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default -> "null"; }; Variation with arrows on the next line: String sinit = switch (typeName) { case "byte", "short", "int" -> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default -> "null"; }; Variation with arrows on the same line, aligned, with case constants one per line: String sinit = switch (typeName) { case "byte", "short", "int" -> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default -> "null"; }; ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From briangoetz at openjdk.java.net Sat Mar 27 01:18:24 2021 From: briangoetz at openjdk.java.net (Brian Goetz) Date: Sat, 27 Mar 2021 01:18:24 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: Message-ID: <-3rNuBQy9vzxAsUtCkit-NJ9nHgcnofhwXSz14JONtk=.511137c1-006d-4d6a-81be-fa30fbf6f78a@github.com> On Sat, 27 Mar 2021 00:39:59 GMT, Stuart Marks wrote: >> Marked as reviewed by briangoetz (Reviewer). > > I have some formatting questions. I also have some weak opinions on formatting, but not strong enough to make recommendations yet. (I see you wrote "Better formatting ideas are welcome" so thanks for being open to this.) I'm interested in feedback on how the code ends up _reading_, particularly from the people who will be maintaining this code. But comments from others are welcome too. > > The switch (c) in `ArgTokenizer::nextToken` is pretty nicely formatted, since each case has a single constant, they're all short, and the values are also all constants that are textually short. The only thing I'd say here is to add a bit of spacing to the default case so that the arrows line up. > > In `Eval::prettyExpr` switch (typeName), the switch is a bit irregular since one of the case arms has multiple constants. This makes it a bit harder to find one if you're looking for it in particular. For example, suppose you want to find out how "int" is handled. In the old code you can scan down looking at each `case` and then look at the constant right next to it. In the new code (as modified) the "int" is farther away from the `case` keyword and is a bit lost among the values, so it's harder to see. Let me see how the variations look. > > (1) Here's the modified version as proposed in the PR: > > String sinit = switch (typeName) { > case "byte", "short", "int" -> "0"; > case "long" -> "0L"; > case "float" -> "0.0f"; > case "double" -> "0.0d"; > case "boolean" -> "false"; > case "char" -> "'\\u0000'"; > default -> "null"; > }; > > (2) Variation with the arrows on the same line, but lined up: > > String sinit = switch (typeName) { > case "byte", "short", "int" -> "0"; > case "long" -> "0L"; > case "float" -> "0.0f"; > case "double" -> "0.0d"; > case "boolean" -> "false"; > case "char" -> "'\\u0000'"; > default -> "null"; > }; > > (3) Variation with arrows on the next line: > > String sinit = switch (typeName) { > case "byte", "short", "int" > -> "0"; > case "long" > -> "0L"; > case "float" > -> "0.0f"; > case "double" > -> "0.0d"; > case "boolean" > -> "false"; > case "char" > -> "'\\u0000'"; > default > -> "null"; > }; > > (4) Variation with arrows on the same line, aligned, with case constants one per line: > > String sinit = switch (typeName) { > case "byte", > "short", > "int" -> "0"; > case "long" -> "0L"; > case "float" -> "0.0f"; > case "double" -> "0.0d"; > case "boolean" -> "false"; > case "char" -> "'\\u0000'"; > default -> "null"; > }; > > Personally I like variations (2) and (4), since they not only line the arrows up, the column of arrows creates a visual divider between the case constants and the values. Variation (3) is quite visually noisy to my eye, though still probably an improvement over the original code (a switch statement, not expression). Are there other variations? What do people think? I'll answer from two perspectives: what I personally like, vs what I would recommend in a style guide. From a personal perspective, I like #2 the best, and #4 after that.? It is really easy to see what's going on.? But, cases where you can actually line up like this are rare, since most switches involve more than just simple constants on the RHS. On the other hand, I would never ask anyone to code like that; it seems too obsessive to ask people to do.? What I'd suggest from a style guide perspective is #1. For this particular example, #3 is the worst on both points. But, this particular example is specific; both the predicates and consequences are syntactically short.? If they were longer, #3 would be more attractive. So as a general recommendation #1 if it fits, #3 if #1 doens't fit, and #2/#4 if the formatting works out and you're feeling generous. On 3/26/2021 8:40 PM, Stuart Marks wrote: > > I have some formatting questions. I also have some weak opinions on > formatting, but not strong enough to make recommendations yet. (I see > you wrote "Better formatting ideas are welcome" so thanks for being > open to this.) I'm interested in feedback on how the code ends up > /reading/, particularly from the people who will be maintaining this > code. But comments from others are welcome too. > > The switch (c) in |ArgTokenizer::nextToken| is pretty nicely > formatted, since each case has a single constant, they're all short, > and the values are also all constants that are textually short. The > only thing I'd say here is to add a bit of spacing to the default case > so that the arrows line up. > > In |Eval::prettyExpr| switch (typeName), the switch is a bit irregular > since one of the case arms has multiple constants. This makes it a bit > harder to find one if you're looking for it in particular. For > example, suppose you want to find out how "int" is handled. In the old > code you can scan down looking at each |case| and then look at the > constant right next to it. In the new code (as modified) the "int" is > farther away from the |case| keyword and is a bit lost among the > values, so it's harder to see. Let me see how the variations look. > > Here's the modified version as proposed in the PR: > > |String sinit = switch (typeName) { case "byte", "short", "int" -> > "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> > "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default > -> "null"; }; | > > Variation with the arrows on the same line, but lined up: > > |String sinit = switch (typeName) { case "byte", "short", "int" -> > "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> > "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default > -> "null"; }; | > > Variation with arrows on the next line: > > |String sinit = switch (typeName) { case "byte", "short", "int" -> > "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> > "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default > -> "null"; }; | > > Variation with arrows on the same line, aligned, with case constants > one per line: > > |String sinit = switch (typeName) { case "byte", "short", "int" -> > "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> > "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default > -> "null"; }; | > > ? > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > , or > unsubscribe > . > ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From smarks at openjdk.java.net Sat Mar 27 05:13:26 2021 From: smarks at openjdk.java.net (Stuart Marks) Date: Sat, 27 Mar 2021 05:13:26 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: <-3rNuBQy9vzxAsUtCkit-NJ9nHgcnofhwXSz14JONtk=.511137c1-006d-4d6a-81be-fa30fbf6f78a@github.com> References: <-3rNuBQy9vzxAsUtCkit-NJ9nHgcnofhwXSz14JONtk=.511137c1-006d-4d6a-81be-fa30fbf6f78a@github.com> Message-ID: On Sat, 27 Mar 2021 01:15:55 GMT, Brian Goetz wrote: >> I have some formatting questions. I also have some weak opinions on formatting, but not strong enough to make recommendations yet. (I see you wrote "Better formatting ideas are welcome" so thanks for being open to this.) I'm interested in feedback on how the code ends up _reading_, particularly from the people who will be maintaining this code. But comments from others are welcome too. >> >> The switch (c) in `ArgTokenizer::nextToken` is pretty nicely formatted, since each case has a single constant, they're all short, and the values are also all constants that are textually short. The only thing I'd say here is to add a bit of spacing to the default case so that the arrows line up. >> >> In `Eval::prettyExpr` switch (typeName), the switch is a bit irregular since one of the case arms has multiple constants. This makes it a bit harder to find one if you're looking for it in particular. For example, suppose you want to find out how "int" is handled. In the old code you can scan down looking at each `case` and then look at the constant right next to it. In the new code (as modified) the "int" is farther away from the `case` keyword and is a bit lost among the values, so it's harder to see. Let me see how the variations look. >> >> (1) Here's the modified version as proposed in the PR: >> >> String sinit = switch (typeName) { >> case "byte", "short", "int" -> "0"; >> case "long" -> "0L"; >> case "float" -> "0.0f"; >> case "double" -> "0.0d"; >> case "boolean" -> "false"; >> case "char" -> "'\\u0000'"; >> default -> "null"; >> }; >> >> (2) Variation with the arrows on the same line, but lined up: >> >> String sinit = switch (typeName) { >> case "byte", "short", "int" -> "0"; >> case "long" -> "0L"; >> case "float" -> "0.0f"; >> case "double" -> "0.0d"; >> case "boolean" -> "false"; >> case "char" -> "'\\u0000'"; >> default -> "null"; >> }; >> >> (3) Variation with arrows on the next line: >> >> String sinit = switch (typeName) { >> case "byte", "short", "int" >> -> "0"; >> case "long" >> -> "0L"; >> case "float" >> -> "0.0f"; >> case "double" >> -> "0.0d"; >> case "boolean" >> -> "false"; >> case "char" >> -> "'\\u0000'"; >> default >> -> "null"; >> }; >> >> (4) Variation with arrows on the same line, aligned, with case constants one per line: >> >> String sinit = switch (typeName) { >> case "byte", >> "short", >> "int" -> "0"; >> case "long" -> "0L"; >> case "float" -> "0.0f"; >> case "double" -> "0.0d"; >> case "boolean" -> "false"; >> case "char" -> "'\\u0000'"; >> default -> "null"; >> }; >> >> Personally I like variations (2) and (4), since they not only line the arrows up, the column of arrows creates a visual divider between the case constants and the values. Variation (3) is quite visually noisy to my eye, though still probably an improvement over the original code (a switch statement, not expression). Are there other variations? What do people think? > > I'll answer from two perspectives: what I personally like, vs what I > would recommend in a style guide. > > From a personal perspective, I like #2 the best, and #4 after that.? It > is really easy to see what's going on.? But, cases where you can > actually line up like this are rare, since most switches involve more > than just simple constants on the RHS. > > On the other hand, I would never ask anyone to code like that; it seems > too obsessive to ask people to do.? What I'd suggest from a style guide > perspective is #1. > > For this particular example, #3 is the worst on both points. > > But, this particular example is specific; both the predicates and > consequences are syntactically short.? If they were longer, #3 would be > more attractive. > > So as a general recommendation #1 if it fits, #3 if #1 doens't fit, and > #2/#4 if the formatting works out and you're feeling generous. > > > On 3/26/2021 8:40 PM, Stuart Marks wrote: >> >> I have some formatting questions. I also have some weak opinions on >> formatting, but not strong enough to make recommendations yet. (I see >> you wrote "Better formatting ideas are welcome" so thanks for being >> open to this.) I'm interested in feedback on how the code ends up >> /reading/, particularly from the people who will be maintaining this >> code. But comments from others are welcome too. >> >> The switch (c) in |ArgTokenizer::nextToken| is pretty nicely >> formatted, since each case has a single constant, they're all short, >> and the values are also all constants that are textually short. The >> only thing I'd say here is to add a bit of spacing to the default case >> so that the arrows line up. >> >> In |Eval::prettyExpr| switch (typeName), the switch is a bit irregular >> since one of the case arms has multiple constants. This makes it a bit >> harder to find one if you're looking for it in particular. For >> example, suppose you want to find out how "int" is handled. In the old >> code you can scan down looking at each |case| and then look at the >> constant right next to it. In the new code (as modified) the "int" is >> farther away from the |case| keyword and is a bit lost among the >> values, so it's harder to see. Let me see how the variations look. >> >> Here's the modified version as proposed in the PR: >> >> |String sinit = switch (typeName) { case "byte", "short", "int" -> >> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >> -> "null"; }; | >> >> Variation with the arrows on the same line, but lined up: >> >> |String sinit = switch (typeName) { case "byte", "short", "int" -> >> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >> -> "null"; }; | >> >> Variation with arrows on the next line: >> >> |String sinit = switch (typeName) { case "byte", "short", "int" -> >> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >> -> "null"; }; | >> >> Variation with arrows on the same line, aligned, with case constants >> one per line: >> >> |String sinit = switch (typeName) { case "byte", "short", "int" -> >> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >> -> "null"; }; | >> >> ? >> You are receiving this because you were mentioned. >> Reply to this email directly, view it on GitHub >> , or >> unsubscribe >> . >> Right, with longer case constants or values, the formatting dynamics of the entire expression change. Here's another example from the changeset, from `Eval::kindOfTree`. (5) Here's the version as proposed in the PR: OuterWrap outer = switch (probableKind) { case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; (6) Line breaks before the arrow: OuterWrap outer = switch (probableKind) { case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; (7) An extra blank line between each case: OuterWrap outer = switch (probableKind) { case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; (8) As above, but with the case constants one to a line: OuterWrap outer = switch (probableKind) { case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From briangoetz at openjdk.java.net Sat Mar 27 15:11:26 2021 From: briangoetz at openjdk.java.net (Brian Goetz) Date: Sat, 27 Mar 2021 15:11:26 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: <-3rNuBQy9vzxAsUtCkit-NJ9nHgcnofhwXSz14JONtk=.511137c1-006d-4d6a-81be-fa30fbf6f78a@github.com> Message-ID: On Sat, 27 Mar 2021 05:10:59 GMT, Stuart Marks wrote: >> I'll answer from two perspectives: what I personally like, vs what I >> would recommend in a style guide. >> >> From a personal perspective, I like #2 the best, and #4 after that.? It >> is really easy to see what's going on.? But, cases where you can >> actually line up like this are rare, since most switches involve more >> than just simple constants on the RHS. >> >> On the other hand, I would never ask anyone to code like that; it seems >> too obsessive to ask people to do.? What I'd suggest from a style guide >> perspective is #1. >> >> For this particular example, #3 is the worst on both points. >> >> But, this particular example is specific; both the predicates and >> consequences are syntactically short.? If they were longer, #3 would be >> more attractive. >> >> So as a general recommendation #1 if it fits, #3 if #1 doens't fit, and >> #2/#4 if the formatting works out and you're feeling generous. >> >> >> On 3/26/2021 8:40 PM, Stuart Marks wrote: >>> >>> I have some formatting questions. I also have some weak opinions on >>> formatting, but not strong enough to make recommendations yet. (I see >>> you wrote "Better formatting ideas are welcome" so thanks for being >>> open to this.) I'm interested in feedback on how the code ends up >>> /reading/, particularly from the people who will be maintaining this >>> code. But comments from others are welcome too. >>> >>> The switch (c) in |ArgTokenizer::nextToken| is pretty nicely >>> formatted, since each case has a single constant, they're all short, >>> and the values are also all constants that are textually short. The >>> only thing I'd say here is to add a bit of spacing to the default case >>> so that the arrows line up. >>> >>> In |Eval::prettyExpr| switch (typeName), the switch is a bit irregular >>> since one of the case arms has multiple constants. This makes it a bit >>> harder to find one if you're looking for it in particular. For >>> example, suppose you want to find out how "int" is handled. In the old >>> code you can scan down looking at each |case| and then look at the >>> constant right next to it. In the new code (as modified) the "int" is >>> farther away from the |case| keyword and is a bit lost among the >>> values, so it's harder to see. Let me see how the variations look. >>> >>> Here's the modified version as proposed in the PR: >>> >>> |String sinit = switch (typeName) { case "byte", "short", "int" -> >>> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >>> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >>> -> "null"; }; | >>> >>> Variation with the arrows on the same line, but lined up: >>> >>> |String sinit = switch (typeName) { case "byte", "short", "int" -> >>> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >>> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >>> -> "null"; }; | >>> >>> Variation with arrows on the next line: >>> >>> |String sinit = switch (typeName) { case "byte", "short", "int" -> >>> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >>> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >>> -> "null"; }; | >>> >>> Variation with arrows on the same line, aligned, with case constants >>> one per line: >>> >>> |String sinit = switch (typeName) { case "byte", "short", "int" -> >>> "0"; case "long" -> "0L"; case "float" -> "0.0f"; case "double" -> >>> "0.0d"; case "boolean" -> "false"; case "char" -> "'\\u0000'"; default >>> -> "null"; }; | >>> >>> ? >>> You are receiving this because you were mentioned. >>> Reply to this email directly, view it on GitHub >>> , or >>> unsubscribe >>> . >>> > > Right, with longer case constants or values, the formatting dynamics of the entire expression change. Here's another example from the changeset, from `Eval::kindOfTree`. > > (5) Here's the version as proposed in the PR: > > OuterWrap outer = switch (probableKind) { > case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); > case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); > }; > > (6) Line breaks before the arrow: > > OuterWrap outer = switch (probableKind) { > case IMPORT > -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); > case EXPRESSION > -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > case VAR, TYPE_DECL, METHOD > -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > default > -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); > }; > > (7) An extra blank line between each case: > > OuterWrap outer = switch (probableKind) { > case IMPORT > -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); > > case EXPRESSION > -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > > case VAR, TYPE_DECL, METHOD > -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > > default > -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); > }; > > (8) As above, but with the case constants one to a line: > > OuterWrap outer = switch (probableKind) { > case IMPORT > -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); > > case EXPRESSION > -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > > case VAR, > TYPE_DECL, > METHOD > -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > > default > -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); > }; > > To my eye, (5) is too dense. The lines are too long. This is indented two levels (one for method in class, the second for code in method) and the longest line is 116 characters long. (Personally I tend to try to keep lines close to 100 or so at most.) The density of the lines makes it difficult to pick out the case constants from the values, as the arrows are buried in the middle. It's impossible to align the arrows, since that would make the lines even longer. > > (6) puts line breaks before each arrow, which is kind of like (3) from the previous round of examples. This is an improvement, I think, and it's tolerable, whereas in the previous round (3) was quite bad. It's still quite dense, however. > > For (7) I simply added line breaks between each case. I think this actually improves things a lot. It still takes up less vertical space than the original switch statement, but the additional white space makes it easier to read, and to pick out the case constants from values, I think. I note that in a switch statement, since `break;` often appears on its own line, it does have the useful effect of separating the case arms with an almost-blank line. Since we don't need `break` here, we have to add a blank line explicitly. > > (8) is a variation of (7) with the case constants on individual lines. The advantage here is that all the constants line up with each other, but frankly I don't think this buys much. It also creates a weird disjointed indent, where the second and subsequent case constants are indented by five because of C-A-S-E-space, but the arrow is at the standard indent of four. You could line up the arrows at an indent level of five, but bleargh, this doesn't really help anything. > > ===== > > From my first round of examples, I said I liked (2) and (4), but revisiting them, I've decided I like (4) less. I suppose I could tolerate (1) but the constants and values being all smashed together makes it difficult to separate them. I'd recommend (2) more strongly because having the arrows all line up provides a clear visual separation between the constants and the values. Of course, the recommendation for (2) stands only if the constants and values can all fit on a single line. > > For the second round of examples, I think adding the blank lines makes a big difference. It means that the switch expression takes up almost as much vertical space as the switch statement. It can save a bit because with the statement, the multiple case labels were each on their own line, whereas for the expression I'm ok with putting the constants on the same line. Even though almost as much vertical space is consumed, I think the readability is quite good, and it still gains the benefits of switch expressions like exhaustiveness and lack of fall-thru. (5) is fine if it fits within reasonable line limits, and is what we should recommend as the starting point. (6) is the natural way to unwrap (5) when the lines get long. (Personally I'm largely indifferent to 6/7/8; they are all acceptable, and I think the distinction is mostly based on how dense and nonuniform the consequences are.) If the consequences are "similar" to each other, or they are simple, then 6 is a winner.? If they start to diverge in subtle ways, adding more whitespace may make it easier for readers to understand what is going on, which might pull us towards 7/8. Like with the previous choices, I might be inclined to do 7 for myself, but I wouldn't want to require others to code that way. I think its in the category of "use more whitespace if you think it makes the code more readable." So: ?- 5 if it fits ?- 6 if you need a little more space ?- 7 or 8 if (6) results in something too dense to read One thing I think you've omitted, but which we should cover, is whether the -> goes on the line with the case, or the consequence: ??? case FOO -> ??????? fooAction() vs ??? case FOO ?????? -> fooAction() I think this is similar to advice for joining two long boolean expressions with &&, or chains of method invocations; it is more obvious that the second line is a continuation of the first when the operator is at the left margin rather than the right.? So I prefer the second to the first (as all your examples used.) On 3/27/2021 1:11 AM, Stuart Marks wrote: > > Right, with longer case constants or values, the formatting dynamics > of the entire expression change. Here's another example from the > changeset, from |Eval::kindOfTree|. > > (5) Here's the version as proposed in the PR: > > |OuterWrap outer = switch (probableKind) { case IMPORT -> > state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case > EXPRESSION -> > state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > case VAR, TYPE_DECL, METHOD -> > state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > default -> > state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | > > (6) Line breaks before the arrow: > > |OuterWrap outer = switch (probableKind) { case IMPORT -> > state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case > EXPRESSION -> > state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > case VAR, TYPE_DECL, METHOD -> > state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > default -> > state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | > > (7) An extra blank line between each case: > > |OuterWrap outer = switch (probableKind) { case IMPORT -> > state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case > EXPRESSION -> > state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > case VAR, TYPE_DECL, METHOD -> > state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > default -> > state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | > > (8) As above, but with the case constants one to a line: > > |OuterWrap outer = switch (probableKind) { case IMPORT -> > state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case > EXPRESSION -> > state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); > case VAR, TYPE_DECL, METHOD -> > state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); > default -> > state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | > > ? > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > , or > unsubscribe > . > ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From tvaleev at openjdk.java.net Sun Mar 28 02:36:57 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Sun, 28 Mar 2021 02:36:57 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v3] In-Reply-To: References: Message-ID: > This change is powered by IntelliJ IDEA quick-fix. > I also took the liberty to fix C-style arrays in changed files. > > In SourceCodeAnalysisImpl.java:501, I left case PARAMETERIZED_TYPE -> FALSE as a separate switch case, because it had a comment. Better formatting ideas are welcome. > > If you like this, I can provide similar PR in other components as well (e.g. in javac) Tagir F. Valeev has updated the pull request incrementally with two additional commits since the last revision: - Remove trailing whitespace - Formatting updated, another expression switch in sourceToSnippets method ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/3210/files - new: https://git.openjdk.java.net/jdk/pull/3210/files/a6501a96..819901b3 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=3210&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=3210&range=01-02 Stats: 38 lines in 2 files changed: 4 ins; 2 del; 32 mod Patch: https://git.openjdk.java.net/jdk/pull/3210.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3210/head:pull/3210 PR: https://git.openjdk.java.net/jdk/pull/3210 From tvaleev at openjdk.java.net Sun Mar 28 02:36:58 2021 From: tvaleev at openjdk.java.net (Tagir F.Valeev) Date: Sun, 28 Mar 2021 02:36:58 GMT Subject: RFR: JDK-8264222: Use switch expression in jshell where possible [v2] In-Reply-To: References: <-3rNuBQy9vzxAsUtCkit-NJ9nHgcnofhwXSz14JONtk=.511137c1-006d-4d6a-81be-fa30fbf6f78a@github.com> Message-ID: On Sat, 27 Mar 2021 15:08:13 GMT, Brian Goetz wrote: >> Right, with longer case constants or values, the formatting dynamics of the entire expression change. Here's another example from the changeset, from `Eval::kindOfTree`. >> >> (5) Here's the version as proposed in the PR: >> >> OuterWrap outer = switch (probableKind) { >> case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); >> case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); >> }; >> >> (6) Line breaks before the arrow: >> >> OuterWrap outer = switch (probableKind) { >> case IMPORT >> -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); >> case EXPRESSION >> -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> case VAR, TYPE_DECL, METHOD >> -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> default >> -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); >> }; >> >> (7) An extra blank line between each case: >> >> OuterWrap outer = switch (probableKind) { >> case IMPORT >> -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); >> >> case EXPRESSION >> -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> >> case VAR, TYPE_DECL, METHOD >> -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> >> default >> -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); >> }; >> >> (8) As above, but with the case constants one to a line: >> >> OuterWrap outer = switch (probableKind) { >> case IMPORT >> -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); >> >> case EXPRESSION >> -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> >> case VAR, >> TYPE_DECL, >> METHOD >> -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> >> default >> -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); >> }; >> >> To my eye, (5) is too dense. The lines are too long. This is indented two levels (one for method in class, the second for code in method) and the longest line is 116 characters long. (Personally I tend to try to keep lines close to 100 or so at most.) The density of the lines makes it difficult to pick out the case constants from the values, as the arrows are buried in the middle. It's impossible to align the arrows, since that would make the lines even longer. >> >> (6) puts line breaks before each arrow, which is kind of like (3) from the previous round of examples. This is an improvement, I think, and it's tolerable, whereas in the previous round (3) was quite bad. It's still quite dense, however. >> >> For (7) I simply added line breaks between each case. I think this actually improves things a lot. It still takes up less vertical space than the original switch statement, but the additional white space makes it easier to read, and to pick out the case constants from values, I think. I note that in a switch statement, since `break;` often appears on its own line, it does have the useful effect of separating the case arms with an almost-blank line. Since we don't need `break` here, we have to add a blank line explicitly. >> >> (8) is a variation of (7) with the case constants on individual lines. The advantage here is that all the constants line up with each other, but frankly I don't think this buys much. It also creates a weird disjointed indent, where the second and subsequent case constants are indented by five because of C-A-S-E-space, but the arrow is at the standard indent of four. You could line up the arrows at an indent level of five, but bleargh, this doesn't really help anything. >> >> ===== >> >> From my first round of examples, I said I liked (2) and (4), but revisiting them, I've decided I like (4) less. I suppose I could tolerate (1) but the constants and values being all smashed together makes it difficult to separate them. I'd recommend (2) more strongly because having the arrows all line up provides a clear visual separation between the constants and the values. Of course, the recommendation for (2) stands only if the constants and values can all fit on a single line. >> >> For the second round of examples, I think adding the blank lines makes a big difference. It means that the switch expression takes up almost as much vertical space as the switch statement. It can save a bit because with the statement, the multiple case labels were each on their own line, whereas for the expression I'm ok with putting the constants on the same line. Even though almost as much vertical space is consumed, I think the readability is quite good, and it still gains the benefits of switch expressions like exhaustiveness and lack of fall-thru. > > (5) is fine if it fits within reasonable line limits, and is what we > should recommend as the starting point. > > (6) is the natural way to unwrap (5) when the lines get long. > (Personally I'm largely indifferent to 6/7/8; they are all acceptable, > and I think the distinction is mostly based on how dense and nonuniform > the consequences are.) > > If the consequences are "similar" to each other, or they are simple, > then 6 is a winner.? If they start to diverge in subtle ways, adding > more whitespace may make it easier for readers to understand what is > going on, which might pull us towards 7/8. > > Like with the previous choices, I might be inclined to do 7 for myself, > but I wouldn't want to require others to code that way. I think its in > the category of "use more whitespace if you think it makes the code more > readable." > > So: > > ?- 5 if it fits > ?- 6 if you need a little more space > ?- 7 or 8 if (6) results in something too dense to read > > One thing I think you've omitted, but which we should cover, is whether > the -> goes on the line with the case, or the consequence: > > ??? case FOO -> > ??????? fooAction() > > vs > > ??? case FOO > ?????? -> fooAction() > > I think this is similar to advice for joining two long boolean > expressions with &&, or chains of method invocations; it is more obvious > that the second line is a continuation of the first when the operator is > at the left margin rather than the right.? So I prefer the second to the > first (as all your examples used.) > > > > On 3/27/2021 1:11 AM, Stuart Marks wrote: >> >> Right, with longer case constants or values, the formatting dynamics >> of the entire expression change. Here's another example from the >> changeset, from |Eval::kindOfTree|. >> >> (5) Here's the version as proposed in the PR: >> >> |OuterWrap outer = switch (probableKind) { case IMPORT -> >> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case >> EXPRESSION -> >> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> case VAR, TYPE_DECL, METHOD -> >> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> default -> >> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | >> >> (6) Line breaks before the arrow: >> >> |OuterWrap outer = switch (probableKind) { case IMPORT -> >> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case >> EXPRESSION -> >> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> case VAR, TYPE_DECL, METHOD -> >> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> default -> >> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | >> >> (7) An extra blank line between each case: >> >> |OuterWrap outer = switch (probableKind) { case IMPORT -> >> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case >> EXPRESSION -> >> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> case VAR, TYPE_DECL, METHOD -> >> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> default -> >> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | >> >> (8) As above, but with the case constants one to a line: >> >> |OuterWrap outer = switch (probableKind) { case IMPORT -> >> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case >> EXPRESSION -> >> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); >> case VAR, TYPE_DECL, METHOD -> >> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); >> default -> >> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; | >> >> ? >> You are receiving this because you were mentioned. >> Reply to this email directly, view it on GitHub >> , or >> unsubscribe >> . >> @briangoetz @stuart-marks thank you for your comments. I don't like (2) because the first case is significantly longer than the other ones. As a result, there's too much of whitespace on the subsequent lines, and it's hard to follow visually from the case label to the resulting expression without the editor's help (e. g. highlighting the current line). (4) solves this problem, so for code reading, it looks the best. There's another consideration though: the code maintenance cost. I'm not sure about other editors but AFAIK, IntelliJ IDEA doesn't help you to maintain the vertical alignment for switch cases (we have a similar option for variable declarations, probably we should support switch cases as well), so any edits of the surrounding code may require manual reformatting, and autoformatting accidentally applied to this code may screw the things up. As for 5-8, there's also an option to align arrows vertically: (9) OuterWrap outer = switch (probableKind) { case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; ` In this case, the longest line has 114 characters, which looks within the surrounding code style. We can also put labels one per line, line in 4. This makes lines even shorter: (10) OuterWrap outer = switch (probableKind) { case IMPORT -> state.outerMap.wrapImport(Wrap.simpleWrap(compileSource), snip); case EXPRESSION -> state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(compileSource)); case VAR, TYPE_DECL, METHOD -> state.outerMap.wrapInTrialClass(Wrap.classMemberWrap(compileSource)); default -> state.outerMap.wrapInTrialClass(Wrap.methodWrap(compileSource)); }; By the way, I found that there's a redundant "preview" warning suppression at line 230. If we remove it and inline the variable, there's another opportunity for an expression switch. I also changed to (4) and (10) and added a space after 'default' in `ArgTokenizer::nextToken`. See the updated PR. ------------- PR: https://git.openjdk.java.net/jdk/pull/3210 From github.com+76791+alblue at openjdk.java.net Sun Mar 28 15:58:43 2021 From: github.com+76791+alblue at openjdk.java.net (Alex Blewitt) Date: Sun, 28 Mar 2021 15:58:43 GMT Subject: RFR: 8264333: Use the blessed modifier order in jdk.jshell Message-ID: 8264333: Use the blessed modifier order in jdk.jshell ------------- Commit messages: - 8264333: Use the blessed modifier order in jdk.jshell Changes: https://git.openjdk.java.net/jdk/pull/3237/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3237&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8264333 Stats: 4 lines in 3 files changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.java.net/jdk/pull/3237.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/3237/head:pull/3237 PR: https://git.openjdk.java.net/jdk/pull/3237 From iris at openjdk.java.net Tue Mar 30 04:41:44 2021 From: iris at openjdk.java.net (Iris Clark) Date: Tue, 30 Mar 2021 04:41:44 GMT Subject: RFR: 8264333: Use the blessed modifier order in jdk.jshell In-Reply-To: References: Message-ID: On Sun, 28 Mar 2021 15:51:52 GMT, Alex Blewitt wrote: > 8264333: Use the blessed modifier order in jdk.jshell Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/3237 From shade at openjdk.java.net Tue Mar 30 07:14:38 2021 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Tue, 30 Mar 2021 07:14:38 GMT Subject: RFR: 8264333: Use the blessed modifier order in jdk.jshell In-Reply-To: References: Message-ID: On Sun, 28 Mar 2021 15:51:52 GMT, Alex Blewitt wrote: > 8264333: Use the blessed modifier order in jdk.jshell Marked as reviewed by shade (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/3237 From github.com+76791+alblue at openjdk.java.net Tue Mar 30 08:19:47 2021 From: github.com+76791+alblue at openjdk.java.net (Alex Blewitt) Date: Tue, 30 Mar 2021 08:19:47 GMT Subject: Integrated: 8264333: Use the blessed modifier order in jdk.jshell In-Reply-To: References: Message-ID: On Sun, 28 Mar 2021 15:51:52 GMT, Alex Blewitt wrote: > 8264333: Use the blessed modifier order in jdk.jshell This pull request has now been integrated. Changeset: 8735259f Author: Alex Blewitt Committer: Aleksey Shipilev URL: https://git.openjdk.java.net/jdk/commit/8735259f Stats: 4 lines in 3 files changed: 0 ins; 0 del; 4 mod 8264333: Use the blessed modifier order in jdk.jshell Reviewed-by: iris, shade ------------- PR: https://git.openjdk.java.net/jdk/pull/3237