Add jep513 module: flexible constructor bodies on JDK 25 and 27
Runnable sources, broken examples and captured transcripts for the ankurm.com JEP 513 article, including the JDK 25 vs 27 compiler wording differences. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
This commit is contained in:
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# JEP 513 (Flexible Constructor Bodies): final in JDK 25, no --enable-preview.
|
||||
# Regenerates every file in output/. JDK25=/path JDK27=/path [JDK21=/path] ./run.sh
|
||||
set -uo pipefail
|
||||
unset JAVA_TOOL_OPTIONS
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
JDK25="${JDK25:-/opt/jdks/jdk-25.0.4.1+1}"; JDK27="${JDK27:-/opt/jdks/jdk27}"; JDK21="${JDK21:-}"
|
||||
OUT="$HERE/output"; mkdir -p "$OUT"; B="$(mktemp -d)"; trap 'rm -rf "$B"' EXIT
|
||||
cd "$HERE"
|
||||
v() { "$1/bin/java" -version 2>&1 | sed -n 2p; }
|
||||
# compile SRC with JDK, then run CLASS from it; prints a header naming the JDK
|
||||
cr() { local jdk="$1" src="$2" cls="$3"; local o="$B/$(basename "$jdk")-$cls"; mkdir -p "$o"
|
||||
echo "\$ javac $src && java $cls ($(v "$jdk"))"
|
||||
"$jdk/bin/javac" -d "$o" "$src" 2>&1 && "$jdk/bin/java" -cp "$o" "$cls" 2>&1; }
|
||||
|
||||
{ cr "$JDK25" src/ValidateBeforeSuper.java ValidateBeforeSuper; echo; cr "$JDK27" src/ValidateBeforeSuper.java ValidateBeforeSuper
|
||||
} > "$OUT/01-validate-before-super.txt"
|
||||
|
||||
{ cr "$JDK25" src/BeforeJava25.java BeforeJava25
|
||||
[ -n "$JDK21" ] && { echo; cr "$JDK21" src/BeforeJava25.java BeforeJava25; }
|
||||
} > "$OUT/02-the-old-workaround.txt"
|
||||
|
||||
{ [ -n "$JDK21" ] && { cr "$JDK21" broken/OnJdk21.java OnJdk21; echo; }
|
||||
cr "$JDK25" broken/OnJdk21.java OnJdk21; echo; cr "$JDK27" broken/OnJdk21.java OnJdk21
|
||||
} > "$OUT/03-same-file-on-21-25-27.txt"
|
||||
|
||||
{ cr "$JDK25" src/OverridableCall.java OverridableCall; } > "$OUT/04-overridable-call-bug-and-fix.txt"
|
||||
|
||||
{ cr "$JDK25" src/ParseThenSuper.java ParseThenSuper; echo; cr "$JDK25" src/TryInPrologue.java TryInPrologue; echo; cr "$JDK25" src/ThisChaining.java ThisChaining
|
||||
} > "$OUT/05-prologue-in-practice.txt"
|
||||
|
||||
{ o="$B/bc"; mkdir -p "$o"; "$JDK25/bin/javac" -d "$o" src/PrologueBytecode.java 2>&1
|
||||
echo "\$ javap -c -p 'PrologueBytecode\$Child' ($(v "$JDK25"))"; "$JDK25/bin/javap" -c -p -cp "$o" 'PrologueBytecode$Child' 2>&1 | sed -n '2,$p'
|
||||
} > "$OUT/06-bytecode.txt"
|
||||
|
||||
# the rules that did not go away: same source, both JDKs, because the wording changed between 25 and 27
|
||||
{ for f in ReadFieldBeforeSuper CallMethodBeforeSuper PassThisBeforeSuper ReadFinalBeforeAssign InnerOuterThis NewInnerBeforeSuper AssignFieldWithInitializer AssignInheritedField ReturnBeforeSuper SuperInBranch TwoSuperCalls; do
|
||||
for j in "$JDK25" "$JDK27"; do
|
||||
echo "\$ javac broken/$f.java ($(v "$j" | sed 's/.*Temurin-//;s/ (build.*//'))"
|
||||
"$j/bin/javac" -d "$B/x" broken/$f.java 2>&1 | grep -E 'error|warning' | sed 's/^broken\///'
|
||||
done; echo
|
||||
done
|
||||
} > "$OUT/07-still-illegal-25-vs-27.txt"
|
||||
# 08 - the language level matters: compiling this source for an older target from JDK 25
|
||||
{ for r in 21 24 25; do echo "\$ javac --release $r broken/OnJdk21.java ($(v "$JDK25" | sed 's/.*Temurin-//;s/ (build.*//'))"
|
||||
"$JDK25/bin/javac" --release $r -d "$B/r$r" broken/OnJdk21.java 2>&1 | grep -v '^Note:' | sed 's/^broken\///'; echo "exit=${PIPESTATUS[0]}"; echo; done
|
||||
} > "$OUT/08-release-levels.txt"
|
||||
echo "wrote $OUT"
|
||||
Reference in New Issue
Block a user