Skip to content

Commit 9eb7d5f

Browse files
committed
add gate style check to prevent non-HotSpot compiler classes importing HotSpot classes
1 parent 7e9ea98 commit 9eb7d5f

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

compiler/mx.compiler/mx_compiler.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,53 @@ def _run_benchmark(suite, name, args, vmargs):
400400
mx.abort("Gate for {} benchmark '{}' failed!".format(suite, name))
401401
return exit_code, suite, results
402402

403+
def _check_forbidden_imports(projects, package_substrings, exceptions=None):
404+
"""
405+
Checks Java source files in `projects` to ensure there is no import from
406+
a class in a package whose name does not match `package_substrings`
407+
of a package whose name matches `package_substrings`.
408+
409+
:param projects: list of JavaProjects
410+
:param package_substrings: package name substrings
411+
:param exceptions: set of unqualified Java source file names for which a failing
412+
check produces a warning instead of an abort
413+
"""
414+
# Assumes package name components start with lower case letter and
415+
# classes start with upper-case letter
416+
importStatementRe = re.compile(r'\s*import\s+(?:static\s+)?([a-zA-Z\d_$\.]+\*?)\s*;\s*')
417+
importedRe = re.compile(r'((?:[a-z][a-zA-Z\d_$]*\.)*[a-z][a-zA-Z\d_$]*)\.(?:(?:[A-Z][a-zA-Z\d_$]*)|\*)')
418+
for project in projects:
419+
for source_dir in project.source_dirs():
420+
for root, _, files in os.walk(source_dir):
421+
java_sources = [name for name in files if name.endswith('.java') and name != 'module-info.java']
422+
if len(java_sources) != 0:
423+
java_package = root[len(source_dir) + 1:].replace(os.sep, '.')
424+
if not any((s in java_package for s in package_substrings)):
425+
for n in java_sources:
426+
java_source = join(root, n)
427+
with open(java_source) as fp:
428+
for i, line in enumerate(fp):
429+
m = importStatementRe.match(line)
430+
if m:
431+
imported = m.group(1)
432+
m = importedRe.match(imported)
433+
lineNo = i + 1
434+
if not m:
435+
mx.abort(java_source + ':' + str(lineNo) + ': import statement does not match expected pattern:\n' + line)
436+
imported_package = m.group(1)
437+
for s in package_substrings:
438+
if s in imported_package:
439+
message = f'{java_source}:{lineNo}: forbidden import of a "{s}" package: {imported_package}\n{line}'
440+
if exceptions and n in exceptions:
441+
mx.warn(message)
442+
else:
443+
mx.abort(message)
444+
403445
def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVMarguments=None, extraUnitTestArguments=None):
446+
with Task('CheckForbiddenImports:Compiler', tasks, tags=['style']) as t:
447+
# Ensure HotSpot-independent compiler classes do not import HotSpot-specific classes
448+
if t: _check_forbidden_imports([mx.project('jdk.internal.vm.compiler')], ('hotspot', 'libgraal'))
449+
404450
with Task('JDK_java_base_test', tasks, tags=['javabasetest'], report=True) as t:
405451
if t: java_base_unittest(_remove_empty_entries(extraVMarguments) + [])
406452

0 commit comments

Comments
 (0)