Skip to content

Commit

Permalink
[GR-58128] Add support for advanced package specs for "opens" attribute.
Browse files Browse the repository at this point in the history
PullRequest: mx/1834
  • Loading branch information
gilles-duboscq committed Sep 13, 2024
2 parents 4e3f2fd + b75de72 commit e866e39
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
16 changes: 8 additions & 8 deletions common.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

"COMMENT.jdks": "When adding or removing JDKs keep in sync with JDKs in ci/common.jsonnet",
"jdks": {
"galahad-jdk": {"name": "jpg-jdk", "version": "24", "build_id": "jdk-24+12-1236", "platformspecific": true, "extrabundles": ["static-libs"]},
"galahad-jdk": {"name": "jpg-jdk", "version": "24", "build_id": "jdk-24+14-1507", "platformspecific": true, "extrabundles": ["static-libs"]},

"oraclejdk11": {"name": "jpg-jdk", "version": "11.0.11", "build_id": "jdk-11.0.11+9", "platformspecific": true, "extrabundles": ["static-libs"] },

Expand Down Expand Up @@ -45,13 +45,13 @@
"labsjdk-ee-21-llvm": {"name": "labsjdk", "version": "ee-21.0.2+13-jvmci-23.1-b33-sulong", "platformspecific": true },
"graalvm-ee-21": {"name": "graalvm-java21", "version": "23.1.3", "platformspecific": true },

"oraclejdk-latest": {"name": "jpg-jdk", "version": "24", "build_id": "jdk-24+12", "platformspecific": true, "extrabundles": ["static-libs"]},
"labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-24+12-jvmci-b01", "platformspecific": true },
"labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-24+12-jvmci-b01-debug", "platformspecific": true },
"labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-24+12-jvmci-b01-sulong", "platformspecific": true },
"labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-24+12-jvmci-b01", "platformspecific": true },
"labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-24+12-jvmci-b01-debug", "platformspecific": true },
"labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-24+12-jvmci-b01-sulong", "platformspecific": true }
"oraclejdk-latest": {"name": "jpg-jdk", "version": "24", "build_id": "jdk-24+14", "platformspecific": true, "extrabundles": ["static-libs"]},
"labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-24+14-jvmci-b01", "platformspecific": true },
"labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-24+14-jvmci-b01-debug", "platformspecific": true },
"labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-24+14-jvmci-b01-sulong", "platformspecific": true },
"labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-24+14-jvmci-b01", "platformspecific": true },
"labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-24+14-jvmci-b01-debug", "platformspecific": true },
"labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-24+14-jvmci-b01-sulong", "platformspecific": true }
},

"eclipse": {
Expand Down
2 changes: 1 addition & 1 deletion src/mx/_impl/mx.py
Original file line number Diff line number Diff line change
Expand Up @@ -18196,7 +18196,7 @@ def alarm_handler(signum, frame):
_CACHE_DIR = get_env('MX_CACHE_DIR', join(dot_mx_dir(), 'cache'))

# The version must be updated for every PR (checked in CI) and the comment should reflect the PR's issue
version = VersionSpec("7.29.7") # GR-57947 replace misstyped 'raise' with 'return'
version = VersionSpec("7.30.0") # advanced opens

_mx_start_datetime = datetime.utcnow()

Expand Down
36 changes: 27 additions & 9 deletions src/mx/_impl/mx_javamodules.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ def make_java_module(dist, jdk, archive, javac_daemon=None, alt_module_info_name
moduleName, _, module_jar = info # pylint: disable=unpacking-non-sequence
exports = {}
requires = {}
opens = {}
opens = []
concealedRequires = {}
base_uses = set()

Expand Down Expand Up @@ -632,7 +632,7 @@ def make_java_module(dist, jdk, archive, javac_daemon=None, alt_module_info_name
for library in java_libraries:
module_packages.update(library.defined_java_packages())

def _parse_packages_spec(packages_spec, available_packages, project_scope):
def _parse_packages_spec(packages_spec, available_packages, project_scope, directive):
"""
Parses a packages specification against a set of available packages:
"org.graalvm.foo,org.graalvm.bar" -> set("org.graalvm.foo", "org.graalvm.bar")
Expand All @@ -643,6 +643,7 @@ def _parse_packages_spec(packages_spec, available_packages, project_scope):
:param dict available_packages: map from package names to JavaCompliance values
:return dict: entries from `available_packages` selected by `packages_spec`
"""
assert directive in ['export', 'open']
if not packages_spec:
mx.abort('exports attribute cannot have entry with empty packages specification', context=dist)
res = set()
Expand All @@ -651,17 +652,20 @@ def _parse_packages_spec(packages_spec, available_packages, project_scope):
prefix = spec[0:-1]
selection = set(p for p in available_packages if p.startswith(prefix))
if not selection:
mx.abort(f'The export package specifier "{spec}" does not match any of {available_packages}', context=dist)
mx.abort(f'The {directive} package specifier "{spec}" does not match any of {available_packages}', context=dist)
res.update(selection)
elif spec == '<package-info>':
if not isinstance(project_scope, mx.Project):
mx.abort('The export package specifier "<package-info>" can only be used in a project, not a distribution', context=dist)
if directive == 'export':
mx.abort('The export package specifier "<package-info>" can only be used in a project, not a distribution', context=dist)
else:
mx.abort(f'The package specifier "<package-info>" cannot be used for the "opens" attribute', context=dist)
res.update(mx._find_packages(project_scope, onlyPublic=True))
else:
if spec not in module_packages:
mx.abort(f'Cannot export package {spec} from {moduleName} as it is not defined by any project in the module {moduleName}', context=dist)
mx.abort(f'Cannot {directive} package {spec} from {moduleName} as it is not defined by any project in the module {moduleName}', context=dist)
if project_scope and spec not in available_packages and project_scope.suite.requiredMxVersion >= mx.VersionSpec("5.226.1"):
mx.abort(f'Package {spec} in "exports" attribute not defined by project {project_scope}', context=project_scope)
mx.abort(f'Package {spec} in "{directive}s" attribute not defined by project {project_scope}', context=project_scope)
res.add(spec)
return res

Expand All @@ -674,15 +678,29 @@ def _process_exports(export_specs, available_packages, project_scope=None):
targets = [n.strip() for n in splitpackage[1].split(',')]
if not targets:
mx.abort('exports attribute must have at least one target for qualified export', context=dist)
for p in _parse_packages_spec(packages_spec, available_packages, project_scope):
for p in _parse_packages_spec(packages_spec, available_packages, project_scope, 'export'):
exports.setdefault(p, set()).update(targets)
else:
unqualified_exports.append(export)

for unqualified_export in unqualified_exports:
for p in _parse_packages_spec(unqualified_export, available_packages, project_scope):
for p in _parse_packages_spec(unqualified_export, available_packages, project_scope, 'export'):
exports[p] = set()

def _process_opens(open_specs, available_packages):
for open_spec in open_specs:
if ' to ' in open_spec:
splitpackage = open_spec.split(' to ')
packages_spec = splitpackage[0].strip()
targets = splitpackage[1]
if not targets.strip():
mx.abort('opens attribute must have at least one target for qualified open', context=dist)
for p in _parse_packages_spec(packages_spec, available_packages, None, 'open'):
opens.append(f"{p} to {targets}")
else:
for p in _parse_packages_spec(open_spec, available_packages, None, 'open'):
opens.append(p)

module_info = getattr(dist, 'moduleInfo', None)
alt_module_info = None

Expand Down Expand Up @@ -752,7 +770,7 @@ def replicate(src, dst):

_process_exports((alt_module_info or module_info).get('exports', []), module_packages)

opens = module_info.get('opens', {})
_process_opens(module_info.get('opens', []), module_packages)
ignored_service_types = module_info.get("ignoredServiceTypes", [])
if not isinstance(ignored_service_types, list):
mx.abort('"ignoredServiceTypes" must be a list', context=dist)
Expand Down

0 comments on commit e866e39

Please sign in to comment.