@@ -400,7 +400,53 @@ def _run_benchmark(suite, name, args, vmargs):
400
400
mx .abort ("Gate for {} benchmark '{}' failed!" .format (suite , name ))
401
401
return exit_code , suite , results
402
402
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
+
403
445
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
+
404
450
with Task ('JDK_java_base_test' , tasks , tags = ['javabasetest' ], report = True ) as t :
405
451
if t : java_base_unittest (_remove_empty_entries (extraVMarguments ) + [])
406
452
0 commit comments