Make `VisitorPartialEvaluator` configurable
- Dominant language
- Java
- Stars
- 2k
- Forks
- 392
- Avg merge
- 11h 24m
- Merged PRs (30d)
- 36
Description
### Motivation
The evaluator performs many optimizations, but sometimes one might want to disable an optimization (because it does not make sense in the context, or the implementation is broken).
For example, one can detect string concatenations that could be format strings:
```java
class MyClass {
private static final String MY_CONSTANT = "some very long string that is repeatedly used";
public static void main(String[] args) {
int value = 1;
System.out.println("This is " + MY_CONSTANT + "!" + value);
}
}
```
and then run `PartialEvaluator` on the suggested code to remove redundant operations like `value + 1 - 1`. For the above the suggestion would be `"This is%s!%d".formatted(value, MY_CONSTANT)`. The `PartialEvaluator` would then inline the known values for `value` and `MY_CONSTANT`, which is not desired.
### Implementation
I do not know how configs for classes should be implemented in java. The java compiler internals use [`Properties`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Properties.html), but this seems like a horrible API.
I am thinking this API might be a good solution:
```java
public enum EvaluatorOption {
INLINE_CONSTANTS,
EVALUATE_CONSTANT_BINARY_OPERATORS,
// ...
}
public class VisitorPartialEvaluatorConfig {
private final boolean enabledByDefault; // true the option is enabled, false it is disabled
private final Map options;
public static VisitorPartialEvaluatorConfig enableEverything() {
return new VisitorPartialEvaluatorConfig(true, new EnumMap<>(EvaluatorOption.class));
}
// same method as above but everything is disabled by default
public boolean isEnabled(EvaluatorOption option) {
return Optional.ofNullable(this.options.get(option)).orElse(this.enabledByDefault)
}
public void set(EvaluatorOption option, boolean isEnabled) {
this.options.put(option, isEnabled);
}
}
```
Alternatives that came to mind:
- Properties, which are bad because strings are used for keys (could result in spelling mistakes without noticing, no compiler error for invalid options)
- Internally use an `EnumSet` instead of a `Map`. Every option that is in the set is enabled and all that are not, will be disabled. The `enableEverything` could then initalize the `Set` with `EvaluatorOption.values()`. (`BitSet` might be an option as well, but performance wise they should be equal and `EnumSet` has type-safety)
- Use a `boolean` attribute for every option and write a getter/setter for each. I would not want to write or maintain that code...
Contributor guide
Assessment
This issue has not been assessed yet.