diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java index b5487f0a926..2f9243ecbd8 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java @@ -2759,6 +2759,11 @@ protected boolean areRestrictedModuleKeywordsActive() { return this.scanContext != null && this.scanContext != ScanContext.INACTIVE; } void updateScanContext(int token) { + if (this.scanContext == ScanContext.AFTER_IMPORT && !isInModuleDeclaration()) { + this.scanContext = ScanContext.INACTIVE; // end temporary use of scanContext to disambiguate module imports + return; + } + switch (token) { case TerminalTokens.TokenNameSEMICOLON: // next could be a KEYWORD case TerminalTokens.TokenNameRBRACE: @@ -3536,10 +3541,14 @@ else if ((data[index] == 'o') && (data[++index] == 'p') && (data[++index] == 'o') && (data[++index] == 'r') - && (data[++index] == 't')) + && (data[++index] == 't')) { + // initialize scanContext, because we need disambiguation when the next token is 'module': + if (this.scanContext == null || this.scanContext == ScanContext.INACTIVE) + this.scanContext = ScanContext.EXPECTING_IDENTIFIER; return TokenNameimport; - else + } else { return TokenNameIdentifier; + } case 9 : if ((data[++index] == 'n') && (data[++index] == 't') @@ -3596,8 +3605,7 @@ else if ((data[index] == 'o') case 'm': //module switch (length) { case 6 : - if ((areRestrictedModuleKeywordsActive() - || this.lookBack[1] == TokenNameimport) // JEP 467: import module + if ((areRestrictedModuleKeywordsActive()) // JEP 467: import module && (data[++index] == 'o') && (data[++index] == 'd') && (data[++index] == 'u') diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleImportTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleImportTests.java index 800021dbade..b321dd02cf6 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleImportTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleImportTests.java @@ -47,7 +47,7 @@ public static Class testClass() { @Override protected StringBuilder trimJavacLog(StringBuilder log) { // suppress preview warnings from javac: - if (log.substring(0, 6).equals("Note: ")) { + if (log.length() > 6 && log.substring(0, 6).equals("Note: ")) { StringBuilder filtered = new StringBuilder(); filtered.append( log.toString().lines() @@ -710,4 +710,40 @@ public class X { "", true); } + + public void test014_moduleAsPackageName_regular() { + List files = new ArrayList<>(); + writeFileCollecting(files, OUTPUT_DIR + File.separator + "module", "Z.java", + """ + package module; + public class Z {} + """); + writeFileCollecting(files, OUTPUT_DIR + File.separator + "test", "X.java", + """ + package test; + import module.Z; + public class X extends Z {} + """); + StringBuilder commandLine = new StringBuilder(" -23 --enable-preview"); + runConformModuleTest(files, commandLine, "", ""); + } + + + public void test014_moduleAsPackageName_moduleInfo() { + List files = new ArrayList<>(); + writeFileCollecting(files, OUTPUT_DIR + File.separator + "module", "Z.java", + """ + package module; + public class Z {} + """); + writeFileCollecting(files, OUTPUT_DIR, "module-info.java", + """ + import module.Z; + module one { + uses Z; + } + """); + StringBuilder commandLine = new StringBuilder(" -23 --enable-preview"); + runConformModuleTest(files, commandLine, "", ""); + } }