diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/SerialGCOptions.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/SerialGCOptions.java index 7ed426612a84..f22ed0d6cf46 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/SerialGCOptions.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/SerialGCOptions.java @@ -127,7 +127,7 @@ public static class ConcealedOptions { } public static class DeprecatedOptions { - @Option(help = "Ignore the maximum heap size while in VM-internal code. Serial GC only.", type = OptionType.Expert, deprecated = true, deprecationMessage = "Please use the option 'IgnoreMaxHeapSizeWhileInVMInternalCode' instead.")// + @Option(help = "Ignore the maximum heap size while in VM-internal code. Serial GC only.", type = OptionType.Expert, deprecated = true, deprecationMessage = "Please use the option 'IgnoreMaxHeapSizeWhileInVMInternalCode' instead")// public static final HostedOptionKey IgnoreMaxHeapSizeWhileInVMOperation = new HostedOptionKey<>(false, SerialGCOptions::validateSerialHostedOption) { @Override protected void onValueUpdate(EconomicMap, Object> values, Boolean oldValue, Boolean newValue) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 77cd68757274..992e4770d593 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -782,7 +782,7 @@ public static boolean hasColorsEnabled(OptionValues values) { @Option(help = "Deprecated, option no longer has any effect.", type = OptionType.User, deprecated = true, deprecationMessage = "It no longer has any effect, and no replacement is available")// public static final HostedOptionKey BuildOutputPrefix = new HostedOptionKey<>(false); - @Option(help = "Color build output (enabled by default if colors are supported by terminal)", type = OptionType.User, deprecated = true, deprecationMessage = "Please use '--color' instead.")// + @Option(help = "Color build output (enabled by default if colors are supported by terminal)", type = OptionType.User, deprecated = true, deprecationMessage = "Please use '--color' instead")// public static final HostedOptionKey BuildOutputColorful = new HostedOptionKey<>(false); @Option(help = "Show links in build output (defaults to the value of BuildOutputColorful)", type = OptionType.User)// @@ -1516,7 +1516,7 @@ public static class TruffleStableOptions { public static final HostedOptionKey ReduceImplicitExceptionStackTraceInformation = new HostedOptionKey<>(false); @Option(help = "Allow all instantiated types to be allocated via Unsafe.allocateInstance().", type = OptionType.Expert, // - deprecated = true, deprecationMessage = "ThrowMissingRegistrationErrors is the preferred way of configuring this on a per-type level.") // + deprecated = true, deprecationMessage = "ThrowMissingRegistrationErrors is the preferred way of configuring this on a per-type level") // public static final HostedOptionKey AllowUnsafeAllocationOfAllInstantiatedTypes = new HostedOptionKey<>(null); @Option(help = "Enable fallback to mremap for initializing the image heap.")// diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java index 74fff342b7d7..5d45fdd5ce18 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java @@ -85,7 +85,7 @@ public static final class Options { AccumulatingLocatableMultiOptionValue.Paths.buildWithCommaDelimiter()); @Option(help = "Resources describing program elements to be made available for reflection (see ProxyConfigurationFiles).", type = OptionType.User, deprecated = true, // deprecationMessage = "This can be caused by a proxy-config.json file in your META-INF directory. " + - "Consider including proxy configuration in the reflection section of reachability-metadata.md instead.")// + "Consider including proxy configuration in the reflection section of reachability-metadata.md instead")// public static final HostedOptionKey DynamicProxyConfigurationResources = new HostedOptionKey<>( AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter()); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/RuntimeOptionParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/RuntimeOptionParser.java index df99572d13f0..1fef113c9d80 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/RuntimeOptionParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/RuntimeOptionParser.java @@ -215,7 +215,7 @@ public void parseOptionAtRuntime(String arg, String optionPrefix, BooleanOptionF // Checkstyle: Allow raw info or warning printing - end String deprecationMessage = descriptor.getDeprecationMessage(); if (deprecationMessage != null && !deprecationMessage.isEmpty()) { - log.string(": ").string(deprecationMessage); + log.string(": ").string(deprecationMessage).string("."); } log.newline(); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java index e4f8be3d9ccc..4c7ddd0b9101 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java @@ -100,7 +100,7 @@ protected void onValueUpdate(EconomicMap, Object> values, String ol }; @Option(help = "Uses the native architecture, i.e., the architecture of a machine that builds an image.", type = User, // - deprecated = true, deprecationMessage = "Please use '-march=native' instead. See '--help' for details.") // + deprecated = true, deprecationMessage = "Please use '-march=native' instead. See '--help' for details") // public static final HostedOptionKey NativeArchitecture = new HostedOptionKey<>(false) { @Override protected void onValueUpdate(EconomicMap, Object> values, Boolean oldValue, Boolean newValue) { @@ -231,7 +231,7 @@ public static void setCommonPoolParallelism(OptionValues optionValues) { } } - @Option(help = "Deprecated, option no longer has any effect", deprecated = true, deprecationMessage = "Please use '--parallelism' instead.")// + @Option(help = "Deprecated, option no longer has any effect", deprecated = true, deprecationMessage = "Please use '--parallelism' instead")// public static final HostedOptionKey NumberOfAnalysisThreads = new HostedOptionKey<>(-1); @Option(help = "Return after analysis")// diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/localization/LocalizationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/localization/LocalizationFeature.java index b8e94e657c6d..2193747b83ce 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/localization/LocalizationFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/localization/LocalizationFeature.java @@ -174,7 +174,7 @@ public static class Options { public static final HostedOptionKey AddAllCharsets = new HostedOptionKey<>(false); @Option(help = "Default locale of the image, by the default it is the same as the default locale of the image builder.", type = OptionType.User, // - deprecated = true, deprecationMessage = "Please switch to using system properties such as '-Duser.country=CH -Duser.language=de'.")// + deprecated = true, deprecationMessage = "Please switch to using system properties such as '-Duser.country=CH -Duser.language=de'")// public static final HostedOptionKey DefaultLocale = new HostedOptionKey<>(Locale.getDefault().toLanguageTag()); @Option(help = "Default charset of the image, by the default it is the same as the default charset of the image builder.", type = OptionType.User)// diff --git a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/option/OptionProcessorTest.java b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/option/OptionProcessorTest.java index b882afb6fc24..9b9a6a95b437 100644 --- a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/option/OptionProcessorTest.java +++ b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/option/OptionProcessorTest.java @@ -384,6 +384,49 @@ public void testOptionValueEqualsAndHashCode() { } + @Test + public void testNoClosingPunctuationInDeprecationMessage() { + TruffleTestAssumptions.assumeWeakEncapsulation(); + Engine engine = createEngineBuilder().build(); + + // Test languages + for (String languageId : engine.getLanguages().keySet()) { + OptionDescriptors descriptors = engine.getLanguages().get(languageId).getOptions(); + checkDescriptorsForClosingPunctuation(descriptors); + } + + // Test instruments + for (String instrumentId : engine.getInstruments().keySet()) { + OptionDescriptors descriptors = engine.getInstruments().get(instrumentId).getOptions(); + checkDescriptorsForClosingPunctuation(descriptors); + } + + // Test explicit test cases for bad deprecation messages + OptionDescriptors descriptors = engine.getLanguages().get("optiontestlang2").getOptions(); + OptionDescriptor deprecatedWithPeriod = descriptors.get("optiontestlang2.DeprecatedWithPeriod"); + if (deprecatedWithPeriod != null) { + String message = deprecatedWithPeriod.getDeprecationMessage(); + assertFalse("Deprecation message should not end with period: " + message, + message != null && message.endsWith(".")); + } + } + + private void checkDescriptorsForClosingPunctuation(OptionDescriptors descriptors) { + for (OptionDescriptor descriptor : descriptors) { + if (descriptor.isDeprecated()) { + String message = descriptor.getDeprecationMessage(); + if (message != null && !message.isEmpty()) { + assertFalse("Deprecation message should not end with period: " + message, + message.endsWith(".")); + assertFalse("Deprecation message should not end with exclamation mark: " + message, + message.endsWith("!")); + assertFalse("Deprecation message should not end with question mark: " + message, + message.endsWith("?")); + } + } + } + } + private static OptionValues getOptionValues(Context c) { c.enter(); try { @@ -444,17 +487,17 @@ public static class OptionError { static final OptionKey> Error9 = OptionKey.mapOf(String.class); @ExpectError("Deprecation message can be specified only for deprecated options.") // - @Option(help = "A", category = OptionCategory.USER, deprecationMessage = "Deprecated with no replacement.") // + @Option(help = "A", category = OptionCategory.USER, deprecationMessage = "Deprecated with no replacement") // static final OptionKey Error10 = new OptionKey<>("defaultValue"); @ExpectError("Option deprecation message must start with upper case letter.") // - @Option(help = "A", category = OptionCategory.USER, deprecated = true, deprecationMessage = "deprecated with no replacement.") // + @Option(help = "A", category = OptionCategory.USER, deprecated = true, deprecationMessage = "deprecated with no replacement") // static final OptionKey Error11 = new OptionKey<>("defaultValue"); @Option(help = "A", name = "", deprecated = true, category = OptionCategory.USER) // static final OptionKey EmptyNameAllowed = new OptionKey<>("defaultValue"); - @Option(help = "A", category = OptionCategory.USER, deprecated = true, deprecationMessage = "Deprecated with no replacement.") // + @Option(help = "A", category = OptionCategory.USER, deprecated = true, deprecationMessage = "Deprecated with no replacement") // static final OptionKey ValidDeprecationMessage = new OptionKey<>("defaultValue"); } @@ -545,6 +588,38 @@ public static Env getCurrentContext() { } + @Registration(id = OptionTestLang2.ID, version = "1.0", name = OptionTestLang2.ID) + public static class OptionTestLang2 extends TruffleLanguage { + + public static final String ID = "optiontestlang2"; + + @Option(help = "Option with bad deprecation message", category = OptionCategory.USER, deprecated = true, deprecationMessage = "This message incorrectly ends with a period.") + static final OptionKey DeprecatedWithPeriod = new OptionKey<>("test"); + + @Option(help = "Option with bad deprecation message", category = OptionCategory.USER, deprecated = true, deprecationMessage = "This message incorrectly ends with an exclamation mark!") + static final OptionKey DeprecatedWithExclamation = new OptionKey<>("test"); + + @Option(help = "Option with good deprecation message", category = OptionCategory.USER, deprecated = true, deprecationMessage = "This message correctly omits closing punctuation") + static final OptionKey DeprecatedWithGoodMessage = new OptionKey<>("test"); + + @Override + protected OptionDescriptors getOptionDescriptors() { + return new OptionTestLang2OptionDescriptors(); + } + + @Override + protected Env createContext(Env env) { + return env; + } + + private static final ContextReference REFERENCE = ContextReference.create(OptionTestLang2.class); + + public static Env getCurrentContext() { + return REFERENCE.get(null); + } + + } + @TruffleInstrument.Registration(id = "optiontestinstr1", services = OptionValues.class) public static class OptionTestInstrument1 extends TruffleInstrument { diff --git a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/Option.java b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/Option.java index 24ced2a6c4d8..c56eed11787e 100644 --- a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/Option.java +++ b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/Option.java @@ -125,7 +125,7 @@ boolean deprecated() default false; /** - * Returns the deprecation reason and the recommended fix. The generated option descriptor + * Returns the deprecation reason and the recommended fix. Do not include closing punctuation. The generated option descriptor * returns this value as result of {@link OptionDescriptor#getDeprecationMessage()}. * * @since 20.1.0 diff --git a/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotEngineOptions.java b/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotEngineOptions.java index 05f33e6560ed..72ad6fc9d095 100644 --- a/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotEngineOptions.java +++ b/truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotEngineOptions.java @@ -78,7 +78,7 @@ final class PolyglotEngineOptions { @Option(category = OptionCategory.INTERNAL, stability = OptionStability.EXPERIMENTAL, help = "Enables conservative context references. " + "This allows invalid sharing between contexts. " + - "For testing purposes only.", deprecated = true, deprecationMessage = "Has no longer any effect. Scheduled for removal in in 22.1.")// + "For testing purposes only.", deprecated = true, deprecationMessage = "Has no longer any effect. Scheduled for removal in in 22.1")// static final OptionKey UseConservativeContextReferences = new OptionKey<>(false); @Option(category = OptionCategory.INTERNAL, stability = OptionStability.EXPERIMENTAL, help = "Enables specialization statistics for nodes generated with Truffle DSL and prints the result on exit. " + diff --git a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmOptions.java b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmOptions.java index e82d7cb64d5f..6130aab570a4 100644 --- a/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmOptions.java +++ b/wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmOptions.java @@ -53,11 +53,11 @@ public class WasmOptions { public static final OptionKey Builtins = new OptionKey<>(""); @Option(help = "The minimal binary size for which to use async parsing. If threads are not supported, async parsing will not be used.", category = OptionCategory.USER, stability = OptionStability.STABLE, usageSyntax = "[0, inf)", // - deprecated = true, deprecationMessage = "Option no longer has any effect and can be safely omitted.")// + deprecated = true, deprecationMessage = "Option no longer has any effect and can be safely omitted")// public static final OptionKey AsyncParsingBinarySize = new OptionKey<>(100_000); @Option(help = "The stack size in kilobytes to use during async parsing, or zero to use defaults.", category = OptionCategory.USER, stability = OptionStability.STABLE, usageSyntax = "[0, inf)", // - deprecated = true, deprecationMessage = "Option no longer has any effect and can be safely omitted.")// + deprecated = true, deprecationMessage = "Option no longer has any effect and can be safely omitted")// public static final OptionKey AsyncParsingStackSize = new OptionKey<>(0); @Option(help = "A comma-separated list of pre-opened Wasi directories.", category = OptionCategory.USER, stability = OptionStability.STABLE, usageSyntax = "[::],[::],...")//