Bug 525713 - [9] Warn when consuming auto modules with unstable names
Change-Id: I372832d10a916c1604a88049bd5166ef928c2f2b
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index 8a5a7b1..625090b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -858,6 +858,7 @@
" methods\n" +
" missingJavadocCommentsVisibility(<visibility>) specify visibility\n" +
" modifier for missing javadoc comments warnings\n" +
+ " module + module related problems.\n" +
" nls string literal lacking non-nls tag //$NON-NLS-<n>$\n" +
" noEffectAssign + assignment without effect\n" +
" null potential missing or redundant null check\n" +
@@ -1107,6 +1108,7 @@
" <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess\" value=\"ignore\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable\" value=\"enabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference\" value=\"enabled\"/>\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index dbc38f8..4388bbd 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -1107,6 +1107,7 @@
expectedProblemAttributes.put("UnsafeRawMethodInvocation", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
expectedProblemAttributes.put("UnsafeReturnTypeOverride", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
expectedProblemAttributes.put("UnsafeTypeConversion", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
+ expectedProblemAttributes.put("UnstableAutoModuleName", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("UnterminatedComment", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("UnterminatedString", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("UnusedConstructorDeclaredThrownException", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
@@ -2002,6 +2003,7 @@
expectedProblemAttributes.put("UnsafeRawMethodInvocation", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
expectedProblemAttributes.put("UnsafeReturnTypeOverride", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
expectedProblemAttributes.put("UnsafeTypeConversion", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
+ expectedProblemAttributes.put("UnstableAutoModuleName", new ProblemAttributes(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME));
expectedProblemAttributes.put("UnterminatedComment", SKIP);
expectedProblemAttributes.put("UnterminatedString", SKIP);
expectedProblemAttributes.put("UnusedConstructorDeclaredThrownException", new ProblemAttributes(JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
index 3a171c0..9a5a624 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
@@ -1985,6 +1985,7 @@
.append(Util.getJavaClassLibsAsString()).append("\" ")
.append("-p \"")
.append(LIB_DIR).append("\" ")
+ .append(" -warn:-module ")
.append(" --module-source-path " + "\"" + directory + "\"");
runConformModuleTest(files,
buffer,
@@ -3432,12 +3433,19 @@
.append(" -classpath \"")
.append(Util.getJavaClassLibsAsString())
.append("\" ")
+ .append(" -info:+module ")
.append(" --module-path " + "\"" + jarPath + "\"");
runConformModuleTest(files,
buffer,
"",
- "",
+ "----------\n" +
+ "1. INFO in ---OUTPUT_DIR_PLACEHOLDER---/src/mod.one/module-info.java (at line 2)\n" +
+ " requires lib.x;\n" +
+ " ^^^^^\n" +
+ "Name of automatic module \'lib.x\' is unstable, it is derived from the module\'s file name.\n" +
+ "----------\n" +
+ "1 problem (1 info)\n",
false,
OUTPUT_DIR + File.separator + out);
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index 7b63883..f90cefc 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -3871,6 +3871,7 @@
new IClasspathAttribute[] {modAttr},
false/*not exported*/);
IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep });
+ p2.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
@@ -4096,6 +4097,7 @@
new IClasspathAttribute[] {modAttr},
false/*not exported*/);
IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2});
+ p3.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
assertMarkers("Unexpected markers", "", markers);
@@ -4167,6 +4169,7 @@
new IClasspathAttribute[] {modAttr},
false/*not exported*/);
IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2});
+ p3.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE);
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
sortMarkers(markers);
@@ -4872,7 +4875,9 @@
IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2});
getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
- assertMarkers("Unexpected markers", "", markers);
+ assertMarkers("Unexpected markers",
+ "Name of automatic module \'com.greetings\' is unstable, it is derived from the module\'s file name.",
+ markers);
} finally {
this.deleteProject("test");
this.deleteProject("com.greetings");
@@ -5079,8 +5084,12 @@
this.problemRequestor.initialize(srcMod.toCharArray());
getWorkingCopy("/mod.one/module-info.java", srcMod, true);
- assertProblems("module-info should have no problems",
+ assertProblems("module-info should have one warning",
"----------\n" +
+ "1. WARNING in /mod.one/module-info.java (at line 2)\n" +
+ " requires lib.x;\n" +
+ " ^^^^^\n" +
+ "Name of automatic module \'lib.x\' is unstable, it is derived from the module\'s file name.\n" +
"----------\n",
this.problemRequestor);
@@ -5307,7 +5316,7 @@
deleteProject(javaProject2);
}
}
- // like testAutoModule3 without name derived from project, not manifest
+ // like testAutoModule3 without name derived from project, not manifest - warning suppressed
public void testAutoModule5() throws Exception {
if (!isJRE9) return;
IJavaProject javaProject = null, auto = null;
@@ -5323,6 +5332,7 @@
addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false));
String srcMod =
+ "@SuppressWarnings(\"module\")\n" +
"module mod.one { \n" +
" requires auto;\n" +
"}";
@@ -5360,6 +5370,47 @@
deleteProject(auto);
}
}
+ // like testAutoModule5, warning configured as ERROR
+ public void testAutoModule6() throws Exception {
+ if (!isJRE9) return;
+ IJavaProject javaProject = null, auto = null;
+ try {
+ auto = createJava9Project("auto", new String[] {"src"});
+ createFolder("auto/src/p/a");
+ createFile("auto/src/p/a/X.java",
+ "package p.a;\n" +
+ "public class X {}\n;");
+
+ javaProject = createJava9Project("mod.one", new String[] {"src"});
+ IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
+ addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false));
+ javaProject.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.ERROR);
+
+ String srcMod =
+ "module mod.one { \n" +
+ " requires auto;\n" +
+ "}";
+ createFile("/mod.one/src/module-info.java",
+ srcMod);
+ auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+
+ this.problemRequestor.initialize(srcMod.toCharArray());
+ getWorkingCopy("/mod.one/module-info.java", srcMod, true);
+ assertProblems("module-info should have only one error",
+ "----------\n" +
+ "1. ERROR in /mod.one/module-info.java (at line 2)\n" +
+ " requires auto;\n" +
+ " ^^^^\n" +
+ "Name of automatic module \'auto\' is unstable, it is derived from the module\'s file name.\n" +
+ "----------\n",
+ this.problemRequestor);
+ } finally {
+ if (javaProject != null)
+ deleteProject(javaProject);
+ if (auto != null)
+ deleteProject(auto);
+ }
+ }
// patch can see unexported type from host (and package accessible method), but not vice versa
public void testPatch1() throws CoreException, IOException {
@@ -6138,8 +6189,12 @@
this.problemRequestor.initialize(srcMod.toCharArray());
getWorkingCopy("/mod1/src/module-info.java", srcMod, true);
- assertProblems("module-info should have no problems",
+ assertProblems("module-info should have exactly one warning",
"----------\n" +
+ "1. WARNING in /mod1/src/module-info.java (at line 3)\n" +
+ " requires automod;\n" +
+ " ^^^^^^^\n" +
+ "Name of automatic module \'automod\' is unstable, it is derived from the module\'s file name.\n" +
"----------\n",
this.problemRequestor);
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index d5ead5d..8c385c1 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -4146,6 +4146,9 @@
} else {
throw new IllegalArgumentException(this.bind("configure.missingJavadocCommentsVisibility", token)); //$NON-NLS-1$
}
+ } else if (token.equals("module")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnstableAutoModuleName, severity, isEnabling);
+ return;
}
break;
case 'n' :
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 1ee5d42..7923d00 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -410,6 +410,7 @@
\ methods\n\
\ missingJavadocCommentsVisibility(<visibility>) specify visibility\n\
\ modifier for missing javadoc comments warnings\n\
+\ module + module related problems.\n\
\ nls string literal lacking non-nls tag //$NON-NLS-<n>$\n\
\ noEffectAssign + assignment without effect\n\
\ null potential missing or redundant null check\n\
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 541060e..b99d196 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -1994,6 +1994,8 @@
int MissingRequiresTransitiveForTypeInAPI = ModuleRelated + 1459;
/** @since 3.14 */
int UnnamedPackageInNamedModule = ModuleRelated + 1460;
+ /** @since 3.14 */
+ int UnstableAutoModuleName = ModuleRelated + 1461;
/** @since 3.13 */
int RedundantNullDefaultAnnotationLocal = Internal + 1062;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index 4891ada..80957aa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -921,6 +921,10 @@
case Binding.MODULE :
SourceModuleBinding module = (SourceModuleBinding) this.recipient;
module.tagBits |= tagBits;
+ if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+ ModuleDeclaration moduleDeclaration = module.scope.referenceContext.moduleDeclaration;
+ recordSuppressWarnings(scope, 0, moduleDeclaration.declarationSourceEnd, compilerOptions.suppressWarnings);
+ }
module.defaultNullness |= defaultNullness;
break;
case Binding.PACKAGE :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RequiresStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RequiresStatement.java
index 918ff43..dbb4187 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RequiresStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/RequiresStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 IBM Corporation and others.
+ * Copyright (c) 2016, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -46,9 +46,12 @@
if (this.resolvedBinding != null)
return this.resolvedBinding;
this.resolvedBinding = this.module.resolve(scope);
- if (this.resolvedBinding == null) {
- if (scope != null)
+ if (scope != null) {
+ if (this.resolvedBinding == null) {
scope.problemReporter().invalidModule(this.module);
+ } else if (this.resolvedBinding.hasUnstableAutoName()) {
+ scope.problemReporter().autoModuleWithUnstableName(this.module);
+ }
}
return this.resolvedBinding;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AutomaticModuleNaming.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AutomaticModuleNaming.java
index bb1c9d1..4c659a3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AutomaticModuleNaming.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AutomaticModuleNaming.java
@@ -62,6 +62,22 @@
}
/**
+ * Determine the automatic module name of a given jar or project as defined by an Automatic-Module-Name
+ * header in its manifest.
+ * @param manifest representation of the META-INF/MANIFEST.MF entry within the given source (jar or project), or <code>null</code>
+ * @return the derived module name or <code>null</code>
+ */
+ public static char[] determineAutomaticModuleNameFromManifest(Manifest manifest) {
+ if (manifest != null) {
+ String automaticModuleName = manifest.getMainAttributes().getValue(AUTOMATIC_MODULE_NAME);
+ if (automaticModuleName != null) {
+ return automaticModuleName.toCharArray();
+ }
+ }
+ return null;
+ }
+
+ /**
* Determine the automatic module name if no "Automatic-Module-Name" was found in the Manifest, as specified in
* {@link <a href=
* "http://download.java.net/java/jdk9/docs/api/java/lang/module/ModuleFinder.html#of-java.nio.file.Path...-">ModuleFinder.of</a>}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModule.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModule.java
index b8915a2..4ea429e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModule.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModule.java
@@ -79,14 +79,19 @@
public default boolean isAutomatic() {
return false;
}
+ public default boolean isAutoNameFromManifest() {
+ return false;
+ }
public abstract boolean isOpen();
- public static IModule createAutomatic(char[] moduleName) {
+ public static IModule createAutomatic(char[] moduleName, boolean fromManifest) {
final class AutoModule implements IModule {
char[] name;
- public AutoModule(char[] name) {
+ boolean nameFromManifest;
+ public AutoModule(char[] name, boolean nameFromManifest) {
this.name = name;
+ this.nameFromManifest = nameFromManifest;
}
@Override
public char[] name() {
@@ -123,14 +128,24 @@
return true;
}
@Override
+ public boolean isAutoNameFromManifest() {
+ return this.nameFromManifest;
+ }
+ @Override
public boolean isOpen() {
return false;
}
}
- return new AutoModule(moduleName);
+ return new AutoModule(moduleName, fromManifest);
}
public static IModule createAutomatic(String fileName, boolean isFile, Manifest manifest) {
- return createAutomatic(AutomaticModuleNaming.determineAutomaticModuleName(fileName, isFile, manifest));
+ boolean fromManifest = true;
+ char[] inferredName = AutomaticModuleNaming.determineAutomaticModuleNameFromManifest(manifest);
+ if (inferredName == null) {
+ fromManifest = false;
+ inferredName = AutomaticModuleNaming.determineAutomaticModuleNameFromFileName(fileName, true, isFile);
+ }
+ return createAutomatic(inferredName, fromManifest);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 453337a..5c129f2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -196,6 +196,7 @@
public static final String OPTION_ReportUnlikelyEqualsArgumentType = "org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType"; //$NON-NLS-1$
public static final String OPTION_ReportAPILeak = "org.eclipse.jdt.core.compiler.problem.APILeak"; //$NON-NLS-1$
+ public static final String OPTION_ReportUnstableAutoModuleName = "org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName"; //$NON-NLS-1$
/**
* Possible values for configurable options
@@ -323,6 +324,7 @@
public static final int UnlikelyEqualsArgumentType = IrritantSet.GROUP2 | ASTNode.Bit23;
public static final int UsingTerminallyDeprecatedAPI = IrritantSet.GROUP2 | ASTNode.Bit24;
public static final int APILeak = IrritantSet.GROUP2 | ASTNode.Bit25;
+ public static final int UnstableAutoModuleName = IrritantSet.GROUP2 | ASTNode.Bit26;
// Severity level for handlers
@@ -521,6 +523,7 @@
"hiding", //$NON-NLS-1$
"incomplete-switch", //$NON-NLS-1$
"javadoc", //$NON-NLS-1$
+ "module", //$NON-NLS-1$
"nls", //$NON-NLS-1$
"null", //$NON-NLS-1$
"rawtypes", //$NON-NLS-1$
@@ -739,6 +742,8 @@
return OPTION_ReportUnlikelyEqualsArgumentType;
case APILeak:
return OPTION_ReportAPILeak;
+ case UnstableAutoModuleName:
+ return OPTION_ReportUnstableAutoModuleName;
}
return null;
}
@@ -1056,6 +1061,8 @@
return "unlikely-arg-type"; //$NON-NLS-1$
case APILeak:
return "exports"; //$NON-NLS-1$
+ case UnstableAutoModuleName:
+ return "module"; //$NON-NLS-1$
}
return null;
}
@@ -1104,6 +1111,10 @@
if ("javadoc".equals(warningToken)) //$NON-NLS-1$
return IrritantSet.JAVADOC;
break;
+ case 'm' :
+ if ("module".equals(warningToken)) //$NON-NLS-1$
+ return IrritantSet.MODULE;
+ break;
case 'n' :
if ("nls".equals(warningToken)) //$NON-NLS-1$
return IrritantSet.NLS;
@@ -1294,6 +1305,7 @@
optionsMap.put(OPTION_ReportUnlikelyCollectionMethodArgumentTypeStrict, this.reportUnlikelyCollectionMethodArgumentTypeStrict ? ENABLED : DISABLED);
optionsMap.put(OPTION_ReportUnlikelyEqualsArgumentType, getSeverityString(UnlikelyEqualsArgumentType));
optionsMap.put(OPTION_ReportAPILeak, getSeverityString(APILeak));
+ optionsMap.put(OPTION_ReportUnstableAutoModuleName, getSeverityString(UnstableAutoModuleName));
return optionsMap;
}
@@ -1812,6 +1824,7 @@
this.analyseResourceLeaks = true;
}
if ((optionValue = optionsMap.get(OPTION_ReportAPILeak)) != null) updateSeverity(APILeak, optionValue);
+ if ((optionValue = optionsMap.get(OPTION_ReportUnstableAutoModuleName)) != null) updateSeverity(UnstableAutoModuleName, optionValue);
if ((optionValue = optionsMap.get(OPTION_AnnotationBasedNullAnalysis)) != null) {
this.isAnnotationBasedNullAnalysisEnabled = ENABLED.equals(optionValue);
}
@@ -2138,6 +2151,7 @@
buf.append("\n\t- unlikely argument type for collection methods, strict check against expected type: ").append(this.reportUnlikelyCollectionMethodArgumentTypeStrict ? ENABLED : DISABLED); //$NON-NLS-1$
buf.append("\n\t- unlikely argument types for equals(): ").append(getSeverityString(UnlikelyEqualsArgumentType)); //$NON-NLS-1$
buf.append("\n\t- API leak: ").append(getSeverityString(APILeak)); //$NON-NLS-1$
+ buf.append("\n\t- unstable auto module name: ").append(getSeverityString(UnstableAutoModuleName)); //$NON-NLS-1$
return buf.toString();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index aa7d95a..e77b9be 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -71,6 +71,7 @@
public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable);
public static final IrritantSet UNLIKELY_ARGUMENT_TYPE = new IrritantSet(CompilerOptions.UnlikelyCollectionMethodArgumentType);
public static final IrritantSet API_LEAK = new IrritantSet(CompilerOptions.APILeak);
+ public static final IrritantSet MODULE = new IrritantSet(CompilerOptions.UnstableAutoModuleName);
public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default
@@ -129,7 +130,8 @@
|CompilerOptions.NonNullTypeVariableFromLegacyInvocation
|CompilerOptions.UnlikelyCollectionMethodArgumentType
|CompilerOptions.UsingTerminallyDeprecatedAPI
- |CompilerOptions.APILeak);
+ |CompilerOptions.APILeak
+ |CompilerOptions.UnstableAutoModuleName);
// default errors IF AnnotationBasedNullAnalysis is enabled:
COMPILER_DEFAULT_ERRORS.set(
CompilerOptions.NullSpecViolation
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryModuleBinding.java
index 7c259d8..88872c5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryModuleBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2017 GK Software AG, and others.
+ * Copyright (c) 2017, 2018 GK Software SE, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -28,15 +28,22 @@
private static class AutomaticModuleBinding extends ModuleBinding {
+ boolean autoNameFromManifest;
+
public AutomaticModuleBinding(IModule module, LookupEnvironment existingEnvironment) {
super(module.name(), existingEnvironment);
existingEnvironment.root.knownModules.put(this.moduleName, this);
this.isAuto = true;
+ this.autoNameFromManifest = module.isAutoNameFromManifest();
this.requires = Binding.NO_MODULES;
this.requiresTransitive = Binding.NO_MODULES;
this.exportedPackages = Binding.NO_PACKAGES;
}
@Override
+ public boolean hasUnstableAutoName() {
+ return !this.autoNameFromManifest;
+ }
+ @Override
public ModuleBinding[] getRequiresTransitive() {
if (this.requiresTransitive == NO_MODULES) {
char[][] autoModules = ((IModuleAwareNameEnvironment)this.environment.nameEnvironment).getAllAutomaticModules();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 0250ff5..091ad47 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -829,6 +829,9 @@
// TODO(SHMOD) implement deprecation for modules
return false;
}
+ public boolean hasUnstableAutoName() {
+ return false;
+ }
public boolean isTransitivelyRequired(ModuleBinding otherModule) {
if (this.transitiveRequires == null) {
Set<ModuleBinding> transitiveDeps = new HashSet<>();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index e697035..59e7d56 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -652,6 +652,8 @@
case IProblem.NotExportedTypeInAPI:
case IProblem.MissingRequiresTransitiveForTypeInAPI:
return CompilerOptions.APILeak;
+ case IProblem.UnstableAutoModuleName:
+ return CompilerOptions.UnstableAutoModuleName;
}
return 0;
}
@@ -714,6 +716,7 @@
case CompilerOptions.UnlikelyCollectionMethodArgumentType :
case CompilerOptions.UnlikelyEqualsArgumentType:
case CompilerOptions.APILeak:
+ case CompilerOptions.UnstableAutoModuleName:
return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
case CompilerOptions.OverriddenPackageDefaultMethod :
@@ -10830,4 +10833,13 @@
0,
0);
}
+
+public void autoModuleWithUnstableName(ModuleReference moduleReference) {
+ String[] args = { new String(moduleReference.moduleName) };
+ handle(IProblem.UnstableAutoModuleName,
+ args,
+ args,
+ moduleReference.sourceStart,
+ moduleReference.sourceEnd);
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index b6f56e6..db8b7c1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -935,6 +935,7 @@
1458 = The type {0} is not exported from this module
1459 = The type {0} from module {1} may not be accessible to clients due to missing ''requires transitive''
1460 = Must declare a named package because this compilation unit is associated to the named module ''{0}''
+1461 = Name of automatic module ''{0}'' is unstable, it is derived from the module's file name.
### ELABORATIONS
## Access restrictions
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 6c8bf76..25819ee 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -1618,6 +1618,27 @@
public static final String COMPILER_PB_API_LEAKS = PLUGIN_ID + ".compiler.problem.APILeak"; //$NON-NLS-1$
/**
+ * Compiler option ID: Reporting when a module requires an auto module with an unstable name.
+ * <p>
+ * The name of an auto module name is considered unstable when it is derived from a file name rather than
+ * being declared in the module's MANIFEST.MF.
+ * <p>
+ * When enabled, the compiler will issue an error or warning when a module references an auto module
+ * with an unstable name in its 'requires' clause.
+ * <dl>
+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName"</code></dd>
+ * <dt>Possible values:</dt>
+ * <dd><code>{ "error", "warning", "info", "ignore" }</code></dd>
+ * <dt>Default:</dt><dd><code>"warning"</code></dd>
+ * </dl>
+ *
+ * @since 3.14
+ * @category CompilerOptionID
+ */
+ public static final String COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME = PLUGIN_ID + ".compiler.problem.unstableAutoModuleName"; //$NON-NLS-1$
+
+
+ /**
* Compiler option ID: Annotation-based Null Analysis.
* <p>This option controls whether the compiler will use null annotations for
* improved analysis of (potential) null references.</p>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java
index 3ff609b..d3a381a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java
@@ -28,8 +28,11 @@
*/
static class AutoModule extends NamedMember implements AbstractModule {
- public AutoModule(JavaElement parent, String name) {
+ private boolean nameFromManifest;
+
+ public AutoModule(JavaElement parent, String name, boolean nameFromManifest) {
super(parent, name);
+ this.nameFromManifest = nameFromManifest;
}
@Override
public IJavaElement[] getChildren() throws JavaModelException {
@@ -39,6 +42,9 @@
public int getFlags() throws JavaModelException {
return 0;
}
+ public boolean isAutoNameFromManifest() {
+ return this.nameFromManifest;
+ }
@Override
public char getHandleMementoDelimiter() {
return JavaElement.JEM_MODULE;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index ab9df20..c947bdb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -3699,8 +3699,13 @@
}
public IModuleDescription getAutomaticModuleDescription() throws JavaModelException {
- char[] moduleName = AutomaticModuleNaming.determineAutomaticModuleName(getElementName(), false, getManifest());
- return new AbstractModule.AutoModule(this, String.valueOf(moduleName));
+ boolean nameFromManifest = true;
+ char[] moduleName = AutomaticModuleNaming.determineAutomaticModuleNameFromManifest(getManifest());
+ if (moduleName == null) {
+ nameFromManifest = false;
+ moduleName = AutomaticModuleNaming.determineAutomaticModuleNameFromFileName(getElementName(), true, false);
+ }
+ return new AbstractModule.AutoModule(this, String.valueOf(moduleName), nameFromManifest);
}
public void setModuleDescription(IModuleDescription module) throws JavaModelException {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
index f544891..869c672 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -43,6 +43,7 @@
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.AbstractModule.AutoModule;
import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
@@ -859,8 +860,9 @@
return ((ModularClassFile) parent).getBinaryModuleInfo();
} else if (moduleDesc instanceof SourceModule) {
return (IModule)((SourceModule) moduleDesc).getElementInfo();
- } else {
- return IModule.createAutomatic(moduleDesc.getElementName().toCharArray());
+ } else if (moduleDesc instanceof AutoModule) {
+ boolean nameFromManifest = ((AutoModule) moduleDesc).isAutoNameFromManifest();
+ return IModule.createAutomatic(moduleDesc.getElementName().toCharArray(), nameFromManifest);
}
} catch (JavaModelException e) {
if (!e.isDoesNotExist())
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 93b4ca0..df40d5f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -928,8 +928,13 @@
elementName = javaProject.getElementName();
break;
}
- char[] moduleName = AutomaticModuleNaming.determineAutomaticModuleName(elementName, isArchive(), manifest);
- return new AbstractModule.AutoModule(this, String.valueOf(moduleName));
+ boolean nameFromManifest = true;
+ char[] moduleName = AutomaticModuleNaming.determineAutomaticModuleNameFromManifest(manifest);
+ if (moduleName == null) {
+ nameFromManifest = false;
+ moduleName = AutomaticModuleNaming.determineAutomaticModuleNameFromFileName(elementName, true, isArchive());
+ }
+ return new AbstractModule.AutoModule(this, String.valueOf(moduleName), nameFromManifest);
}
/** @see org.eclipse.jdt.internal.compiler.env.IModulePathEntry#hasCompilationUnit(String, String) */