Skip to content

Instantly share code, notes, and snippets.

@sormuras
Created August 16, 2022 14:25
Show Gist options
  • Save sormuras/a9b923e3bf7ed344a92b6e2f0dfdd840 to your computer and use it in GitHub Desktop.
Save sormuras/a9b923e3bf7ed344a92b6e2f0dfdd840 to your computer and use it in GitHub Desktop.
Replace Program's printGreeting() method
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
public class Generator extends Program {
public static void main(String... args) {
var program = loadString("Program.java");
var replacer = new Replacer(loadString("Generator.java"));
program = replacer.replace(
"^\\Q void printGreeting() {\\E(.*?)^\\Q }\\E",
program,
replacement ->
replacement
.replace(
"${USER}",
args.length == 0
? System.getProperty("user.name", "Nobody")
: String.join(" ", args))
.stripTrailing());
System.out.println(program);
}
@Override
void printGreeting() {
System.out.println("Hello ${USER}");
}
record Replacer(String generatorSource) {
String replace(String regex, String program, UnaryOperator<String> operator) {
var pattern = Pattern.compile(regex, Pattern.DOTALL + Pattern.MULTILINE);
var generatorMatcher = pattern.matcher(generatorSource);
if (!generatorMatcher.find()) throw new Error("Pattern not found in generator: " + pattern);
var replacement = operator.apply(generatorMatcher.group());
var matcher = pattern.matcher(program);
if (!matcher.find())
throw new Error("Pattern not found in program: " + matcher);
return matcher.replaceFirst(replacement);
}
}
private static String loadString(String name) {
var path = Path.of(name);
try {
if (Files.isReadable(path)) return Files.readString(path);
try (var stream = Generator.class.getResourceAsStream(name)) {
if (stream == null) throw new Error("file/resource not found: " + name);
return new String(stream.readAllBytes());
}
} catch (Exception exception) {
throw new Error(exception);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment