Skip to content

Commit b5ba17d

Browse files
authored
Merge pull request #4880 from mwichmann/maint/java-versioning
Java versioning update to current
2 parents 0c2b800 + 92fb570 commit b5ba17d

4 files changed

Lines changed: 61 additions & 58 deletions

File tree

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
143143
- Some cleanups in Subst.py. Functionality does not change.
144144
- Deprecate the legacy job scheduler and feature flag. The feature flag
145145
is renamed to "legacy_sched_deprecated".
146+
- Java tool recognizes all released versions, and no longer needs manual
147+
updating as new releases are made. Default is now latest LTS - v25.
146148
- Reference manual improvements:
147149
* More clarifications in Builder Methods section.
148150
* Clarify VariantDir behavior when switching from duplicate=True (the

RELEASE.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ long function signature lines, and some linting-inspired cleanups.
112112
- Add RequiredPackage to the LaTeX scanner for recursive scanning of custom
113113
LaTeX packages.
114114

115+
- Java tool recognizes all released versions, and no longer needs manual
116+
updating as new releases are made. Default is now latest LTS - v25.
117+
115118
PACKAGING
116119
---------
117120

SCons/Tool/JavaCommon.py

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,40 @@
3535

3636
java_parsing = True
3737

38-
default_java_version = '1.4'
38+
default_java_version = '25.0'
3939

40-
# a switch for which jdk versions to use the Scope state for smarter
41-
# anonymous inner class parsing.
42-
scopeStateVersions = ('1.8',)
40+
# Ancient Java versions that require special handling for anonymous inner classes.
41+
# Versions from 1.5 onwards use the modern stack-based behavior.
42+
ANCIENT_JAVA_VERSIONS = ('1.1', '1.2', '1.3', '1.4')
43+
44+
45+
def _version_uses_scope_state(version: str) -> bool:
46+
"""Determine if a Java version uses ScopeState for anonymous inner classes.
47+
48+
Only Java 1.8 and newer versions benefit from ScopeState tracking.
49+
50+
Args:
51+
version: Java version string (e.g., '1.8', '11.0', '21', '26.0')
52+
53+
Returns:
54+
True if the version should use ScopeState, False otherwise.
55+
"""
56+
# Ancient versions never use ScopeState
57+
if version in ANCIENT_JAVA_VERSIONS:
58+
return False
59+
60+
try:
61+
# Handle "1.X" format (e.g., "1.5", "1.6", "1.7", "1.8")
62+
if version.startswith('1.'):
63+
minor = int(version[2:].split('.')[0])
64+
return minor >= 8 # 1.8 and later
65+
else:
66+
# Handle "X" or "X.Y" format (e.g., "9", "11.0", "21")
67+
major = int(version.split('.')[0])
68+
return major >= 9 # Java 9 and later (which is Java 1.9, so >= 1.8)
69+
except (ValueError, IndexError):
70+
# If we can't parse it, assume it's a modern version
71+
return True
4372

4473
# Glob patterns for use in finding where the JDK is.
4574
#
@@ -105,33 +134,18 @@ class OuterState:
105134
interfaces, and anonymous inner classes."""
106135

107136
def __init__(self, version=default_java_version) -> None:
108-
if version not in (
109-
'1.1',
110-
'1.2',
111-
'1.3',
112-
'1.4',
113-
'1.5',
114-
'1.6',
115-
'1.7',
116-
'1.8',
117-
'5',
118-
'6',
119-
'9.0',
120-
'10.0',
121-
'11.0',
122-
'12.0',
123-
'13.0',
124-
'14.0',
125-
'15.0',
126-
'16.0',
127-
'17.0',
128-
'18.0',
129-
'19.0',
130-
'20.0',
131-
'21.0',
132-
):
133-
msg = "Java version %s not supported" % version
134-
raise NotImplementedError(msg)
137+
# Validate that this is a recognized Java version format.
138+
# We accept any reasonable version string; only ancient versions (1.1-1.4)
139+
# require special handling. Assume future Java versions are fine until
140+
# proven otherwise (this replaces earlier explicit lists of "good" versions).
141+
try:
142+
if version not in ANCIENT_JAVA_VERSIONS:
143+
# For modern versions, do basic validation of format
144+
parts = version.split('.')
145+
if not parts[0].isdigit():
146+
raise ValueError(f"Invalid Java version format: {version}")
147+
except (AttributeError, ValueError):
148+
raise ValueError(f"Invalid Java version format: {version}")
135149

136150
self.version = version
137151
self.listClasses = []
@@ -197,7 +211,7 @@ def closeBracket(self) -> None:
197211
self.stackBrackets.pop()
198212
if len(self.stackAnonClassBrackets) and \
199213
self.brackets == self.stackAnonClassBrackets[-1] and \
200-
self.version not in scopeStateVersions:
214+
not _version_uses_scope_state(self.version):
201215
self._getAnonStack().pop()
202216
self.stackAnonClassBrackets.pop()
203217

@@ -232,32 +246,16 @@ def parseToken(self, token):
232246
return self
233247

234248
def addAnonClass(self) -> None:
235-
"""Add an anonymous inner class"""
236-
if self.version in ('1.1', '1.2', '1.3', '1.4'):
249+
"""Add an anonymous inner class.
250+
251+
Modern versions (1.5+) use scope-based parsing for more accurate handling.
252+
Ancient versions (1.1-1.4) use simple sequential numbering.
253+
"""
254+
if self.version in ANCIENT_JAVA_VERSIONS:
255+
# Ancient Java versions: simple sequential numbering
237256
clazz = self.listClasses[0]
238257
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
239-
# TODO: shouldn't need to repeat versions here and in OuterState
240-
elif self.version in (
241-
'1.5',
242-
'1.6',
243-
'1.7',
244-
'1.8',
245-
'5',
246-
'6',
247-
'9.0',
248-
'10.0',
249-
'11.0',
250-
'12.0',
251-
'13.0',
252-
'14.0',
253-
'15.0',
254-
'16.0',
255-
'17.0',
256-
'18.0',
257-
'19.0',
258-
'20.0',
259-
'21.0',
260-
):
258+
else:
261259
self.stackAnonClassBrackets.append(self.brackets)
262260
className = []
263261
className.extend(self.listClasses)
@@ -376,7 +374,7 @@ def parseToken(self, token):
376374
return self
377375
if token == '{':
378376
self.outer_state.addAnonClass()
379-
if self.outer_state.version in scopeStateVersions:
377+
if _version_uses_scope_state(self.outer_state.version):
380378
return ScopeState(old_state=self.old_state).parseToken(token)
381379
return self.old_state.parseToken(token)
382380

SCons/Tool/javac.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def find_java_files(arg, dirpath, filenames) -> None:
8585
else:
8686
raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % entry.__class__)
8787

88-
version = env.get('JAVAVERSION', '1.4')
88+
version = env.get('JAVAVERSION', '25.0')
8989
full_tlist = []
9090
for f in slist:
9191
tlist = []

0 commit comments

Comments
 (0)