diff options
| author | Stephan Herrmann | 2018-02-17 20:24:11 +0000 |
|---|---|---|
| committer | Stephan Herrmann | 2018-02-17 22:33:10 +0000 |
| commit | ab20dcc315da3b88242cf9c4ff39323b4a718aa0 (patch) | |
| tree | cb998bed435898ead892b13dcb11e404e715352a | |
| parent | b1610eaae0a778a35578b340fad9351bd90c7b39 (diff) | |
| download | eclipse.jdt.core-ab20dcc315da3b88242cf9c4ff39323b4a718aa0.tar.gz eclipse.jdt.core-ab20dcc315da3b88242cf9c4ff39323b4a718aa0.tar.xz eclipse.jdt.core-ab20dcc315da3b88242cf9c4ff39323b4a718aa0.zip | |
Change-Id: I372832d10a916c1604a88049bd5166ef928c2f2b
22 files changed, 215 insertions, 26 deletions
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 8a5a7b1d0a..625090b487 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 @@ public void test012b(){ " 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 @@ public void test012b(){ " <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 dbc38f86ac..4388bbd6a1 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 @@ public void test011_problem_categories() { 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 @@ public void test012_compiler_problems_tuning() { 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 3a171c05cb..9a5a6244d0 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 @@ public class ModuleCompilationTests extends AbstractBatchCompilerTest { .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 @@ public class ModuleCompilationTests extends AbstractBatchCompilerTest { .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 7b6388301d..f90cefcf3a 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 @@ public class ModuleBuilderTests extends ModifyingResourceTests { 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 d5ead5dac8..8c385c1ca0 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 @@ private void handleErrorOrWarningToken(String token, boolean isEnabling, int sev } 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 1ee5d426b5..7923d00a1c 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 @@ misc.usage.warn = {1} {2}\n\ \ 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 541060ef88..b99d196e8b 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 @@ void setSourceStart(int sourceStart); 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 4891ada384..80957aac43 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 @@ public abstract class Annotation extends Expression { 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 918ff43ada..dbb4187841 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 @@ public class RequiresStatement extends ModuleStatement { 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 bb1c9d1a32..4c659a366f 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 @@ public class AutomaticModuleNaming { } /** + * 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 b8915a2bca..4ea429eadf 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 interface IModule { 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 @@ public interface IModule { 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 453337afdd..5c129f2cc2 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 class CompilerOptions { 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 class CompilerOptions { 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 @@ public class CompilerOptions { "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 @@ public class CompilerOptions { return OPTION_ReportUnlikelyEqualsArgumentType; case APILeak: return OPTION_ReportAPILeak; + case UnstableAutoModuleName: + return OPTION_ReportUnstableAutoModuleName; } return null; } @@ -1056,6 +1061,8 @@ public class CompilerOptions { 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 @@ public class CompilerOptions { 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 @@ public class CompilerOptions { 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 @@ public class CompilerOptions { 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 @@ public class CompilerOptions { 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 aa7d95af73..e77b9be3ca 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 class IrritantSet { 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 @@ public class IrritantSet { |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 7c259d8f18..88872c5698 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 @@ public class BinaryModuleBinding extends ModuleBinding { 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 0250ff5113..091ad47518 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 @@ public class ModuleBinding extends Binding implements IUpdatableModule { // 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 e6970353b7..59e7d5621a 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 @@ public static int getIrritant(int problemID) { case IProblem.NotExportedTypeInAPI: case IProblem.MissingRequiresTransitiveForTypeInAPI: return CompilerOptions.APILeak; + case IProblem.UnstableAutoModuleName: + return CompilerOptions.UnstableAutoModuleName; } return 0; } @@ -714,6 +716,7 @@ public static int getProblemCategory(int severity, int problemID) { 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 @@ public void unnamedPackageInNamedModule(ModuleBinding module) { 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 b6f56e66a0..db8b7c1703 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 6c8bf763f2..25819eea45 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 final class JavaCore extends Plugin { 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 3ff609b14b..d3a381a347 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 @@ public interface AbstractModule extends IModuleDescription { */ 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 interface AbstractModule extends IModuleDescription { 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 ab9df20290..c947bdb2fe 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 class JavaProject } 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 f544891680..869c672811 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.lookup.TypeConstants; 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 @@ public class NameLookup implements SuffixConstants { 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 93b4ca0990..df40d5ff84 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 @@ IModuleDescription getAutomaticModuleDescription(IClasspathEntry classpathEntry) 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) */ |
