Skip to content

Commit cc92dee

Browse files
committed
[GR-42671] Implement LocatableMultiOptionValue with built-in separator support and LocatableMultiOptionValue.Paths.
PullRequest: graal/13204
2 parents 28e40c5 + dbf5091 commit cc92dee

File tree

21 files changed

+166
-125
lines changed

21 files changed

+166
-125
lines changed

substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/option/CommonOptionParser.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
package com.oracle.svm.common.option;
2828

2929
import java.io.PrintStream;
30+
import java.nio.file.Path;
3031
import java.util.ArrayList;
3132
import java.util.Arrays;
3233
import java.util.Comparator;
@@ -312,8 +313,6 @@ static Object parseValue(Class<?> optionType, OptionKey<?> optionKey, LocatableO
312313
value = (int) longValue;
313314
} else if (optionType == Long.class) {
314315
value = parseLong(valueString);
315-
} else if (optionType == String.class) {
316-
value = valueString;
317316
} else if (optionType == Double.class) {
318317
value = parseDouble(valueString);
319318
} else if (optionType == Boolean.class) {
@@ -324,6 +323,25 @@ static Object parseValue(Class<?> optionType, OptionKey<?> optionKey, LocatableO
324323
} else {
325324
return OptionParseResult.error("Boolean option " + option + " must have value 'true' or 'false'");
326325
}
326+
} else if (optionType == String.class || optionType == Path.class) {
327+
Object defaultValue = optionKey.getDefaultValue();
328+
String delimiter = defaultValue instanceof MultiOptionValue ? ((MultiOptionValue<?>) defaultValue).getDelimiter() : "";
329+
boolean multipleValues = !delimiter.isEmpty() && valueString.contains(delimiter);
330+
String[] valueStrings = multipleValues ? StringUtil.split(valueString, delimiter) : null;
331+
if (optionType == String.class) {
332+
value = valueStrings != null ? valueStrings : valueString;
333+
} else {
334+
assert optionType == Path.class;
335+
if (valueStrings != null) {
336+
Path[] valuePaths = new Path[valueStrings.length];
337+
for (int i = 0; i < valueStrings.length; i++) {
338+
valuePaths[i] = Path.of(valueStrings[i]);
339+
}
340+
value = valuePaths;
341+
} else {
342+
value = Path.of(valueString);
343+
}
344+
}
327345
} else if (optionType.isEnum()) {
328346
value = Enum.valueOf(optionType.asSubclass(Enum.class), valueString);
329347
} else if (optionType == EconomicSet.class) {

substratevm/src/com.oracle.svm.common/src/com/oracle/svm/common/option/MultiOptionValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public interface MultiOptionValue<T> {
3131

3232
Class<T> getValueType();
3333

34+
String getDelimiter();
35+
3436
/**
3537
* @return a list of option values, one for each place where the option is used.
3638
*/

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
import com.oracle.svm.core.option.HostedOptionKey;
6464
import com.oracle.svm.core.option.HostedOptionValues;
6565
import com.oracle.svm.core.option.LocatableMultiOptionValue;
66-
import com.oracle.svm.core.option.OptionUtils;
6766
import com.oracle.svm.core.option.RuntimeOptionKey;
6867
import com.oracle.svm.core.thread.VMOperationControl;
6968
import com.oracle.svm.core.util.UserError;
@@ -91,7 +90,7 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
9190
@Option(help = "Preserve the local variable information for every Java source line to allow line-by-line stepping in the debugger. Allow the lookup of Java-level method information, e.g., in stack traces.")//
9291
public static final HostedOptionKey<Boolean> SourceLevelDebug = new HostedOptionKey<>(false);
9392
@Option(help = "Constrain debug info generation to the comma-separated list of package prefixes given to this option.")//
94-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> SourceLevelDebugFilter = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
93+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> SourceLevelDebugFilter = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
9594

9695
public static boolean parseOnce() {
9796
/*
@@ -186,9 +185,8 @@ private static Predicate<String> makeFilter(List<String> definedFilters) {
186185
if (definedFilters.isEmpty()) {
187186
return javaName -> true;
188187
}
189-
List<String> wildCardList = OptionUtils.flatten(",", definedFilters);
190188
return javaName -> {
191-
for (String wildCard : wildCardList) {
189+
for (String wildCard : definedFilters) {
192190
if (javaName.startsWith(wildCard)) {
193191
return true;
194192
}
@@ -282,10 +280,10 @@ public static void setDebugInfoValueUpdateHandler(ValueUpdateHandler<Integer> up
282280
public static final HostedOptionKey<Boolean> IncludeNodeSourcePositions = new HostedOptionKey<>(false);
283281

284282
@Option(help = "Search path for C libraries passed to the linker (list of comma-separated directories)")//
285-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> CLibraryPath = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
283+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> CLibraryPath = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
286284

287285
@Option(help = "Path passed to the linker as the -rpath (list of comma-separated directories)")//
288-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> LinkerRPath = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
286+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> LinkerRPath = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
289287

290288
@Option(help = "Directory of the image file to be generated", type = OptionType.User)//
291289
public static final HostedOptionKey<String> Path = new HostedOptionKey<>(null);
@@ -375,11 +373,11 @@ public Boolean getValue(OptionValues values) {
375373

376374
@APIOption(name = "trace-class-initialization")//
377375
@Option(help = "Comma-separated list of fully-qualified class names that class initialization is traced for.")//
378-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> TraceClassInitialization = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
376+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> TraceClassInitialization = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
379377

380378
@APIOption(name = "trace-object-instantiation")//
381379
@Option(help = "Comma-separated list of fully-qualified class names that object instantiation is traced for.")//
382-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> TraceObjectInstantiation = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
380+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> TraceObjectInstantiation = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
383381

384382
@Option(help = "Trace all native tool invocations as part of image building", type = User)//
385383
public static final HostedOptionKey<Boolean> TraceNativeToolUsage = new HostedOptionKey<>(false);
@@ -394,10 +392,10 @@ public Boolean getValue(OptionValues values) {
394392
@APIOption(name = "enable-https", fixedValue = "https", customHelp = "enable https support in the generated image")//
395393
@APIOption(name = "enable-url-protocols")//
396394
@Option(help = "List of comma separated URL protocols to enable.")//
397-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> EnableURLProtocols = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
395+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> EnableURLProtocols = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
398396

399397
@Option(help = "List of comma separated URL protocols that must never be included.")//
400-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> DisableURLProtocols = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
398+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> DisableURLProtocols = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
401399

402400
@SuppressWarnings("unused") //
403401
@APIOption(name = "enable-all-security-services")//
@@ -659,7 +657,7 @@ public static void defaultDebugInfoValueUpdateHandler(EconomicMap<OptionKey<?>,
659657
}
660658

661659
@Option(help = "Search path for source files for Application or GraalVM classes (list of comma-separated directories or jar files)")//
662-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> DebugInfoSourceSearchPath = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings());
660+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> DebugInfoSourceSearchPath = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated());
663661

664662
@Option(help = "Directory under which to create source file cache for Application or GraalVM classes")//
665663
public static final HostedOptionKey<String> DebugInfoSourceCacheRoot = new HostedOptionKey<>("sources");

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/VMInspectionOptions.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import com.oracle.svm.core.option.APIOption;
4040
import com.oracle.svm.core.option.HostedOptionKey;
4141
import com.oracle.svm.core.option.LocatableMultiOptionValue;
42-
import com.oracle.svm.core.option.OptionUtils;
4342
import com.oracle.svm.core.option.SubstrateOptionsParser;
4443
import com.oracle.svm.core.util.UserError;
4544

@@ -55,7 +54,7 @@ public final class VMInspectionOptions {
5554
@APIOption(name = ENABLE_MONITORING_OPTION, defaultValue = MONITORING_ALL_NAME) //
5655
@Option(help = "Enable monitoring features that allow the VM to be inspected at run time. Comma-separated list can contain " + MONITORING_ALLOWED_VALUES + ". " +
5756
"For example: `--" + ENABLE_MONITORING_OPTION + "=" + MONITORING_HEAPDUMP_NAME + "," + MONITORING_JVMSTAT_NAME + "`.", type = OptionType.User) //
58-
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> EnableMonitoringFeatures = new HostedOptionKey<>(new LocatableMultiOptionValue.Strings(),
57+
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> EnableMonitoringFeatures = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.commaSeparated(),
5958
VMInspectionOptions::validateEnableMonitoringFeatures);
6059

6160
public static void validateEnableMonitoringFeatures(OptionKey<?> optionKey) {
@@ -72,7 +71,7 @@ public static String getHeapdumpsCommandArgument() {
7271
}
7372

7473
public static Set<String> getEnabledMonitoringFeatures() {
75-
return new HashSet<>(OptionUtils.flatten(",", EnableMonitoringFeatures.getValue()));
74+
return new HashSet<>(EnableMonitoringFeatures.getValue().values());
7675
}
7776

7877
private static boolean hasAllOrKeywordMonitoringSupport(String keyword) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/ProjectHeaderFile.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@
3737
import org.graalvm.nativeimage.hosted.Feature;
3838

3939
import com.oracle.svm.core.SubstrateOptions;
40-
import com.oracle.svm.core.feature.InternalFeature;
41-
import com.oracle.svm.core.option.OptionUtils;
4240
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4341
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
42+
import com.oracle.svm.core.feature.InternalFeature;
4443
import com.oracle.svm.core.util.VMError;
4544

4645
@AutomaticallyRegisteredFeature
@@ -170,7 +169,7 @@ static class MainHeaderResolver implements HeaderResolver {
170169
@Override
171170
public HeaderSearchResult resolveHeader(String projectName, String headerFile) {
172171
List<String> locations = new ArrayList<>();
173-
for (String clibPathComponent : OptionUtils.flatten(",", SubstrateOptions.CLibraryPath.getValue())) {
172+
for (String clibPathComponent : SubstrateOptions.CLibraryPath.getValue().values()) {
174173
Path clibPathHeaderFile = Paths.get(clibPathComponent).resolve(headerFile).normalize().toAbsolutePath();
175174
locations.add(clibPathHeaderFile.toString());
176175
if (Files.exists(clibPathHeaderFile)) {

0 commit comments

Comments
 (0)