Я некоторое время пытался найти решение этой проблемы. Надеюсь, вы мне поможете.
Я пытаюсь сгенерировать метод, который вызывает метод stati c из другого класса, используя некоторые уже определенные поля:
class Test {
private String someField;
private String otherField;
}
Ожидаемый результат:
class Test {
private String someField;
private String otherField;
public String getCacheKey() {
return SimpleCacheKey.of(this.someField, this.otherField);
}
}
class SimpleCacheKey {
public static String of(final Object... values) {
// Some Operations
return computed_string;
}
}
Я пробовал несколько самых близких вещей:
public class ModelProcessor implements Plugin {
@Override
public Builder<?> apply(final Builder<?> builder,
final TypeDescription typeDescription,
final ClassFileLocator classFileLocator) {
return builder.defineMethod("getCacheKey", String.class, Visibility.PUBLIC)
.intercept(new SimpleCacheKeyImplementation());
}
@Override
public void close() throws IOException {
}
@Override
public boolean matches(final TypeDescription typeDefinitions) {
return true;
}
}
public class SimpleCacheKeyImplementation implements Implementation {
private static final MethodDescription SIMPLE_CACHE_KEY_OF = getOf();
@SneakyThrows
private static MethodDescription.ForLoadedMethod getOf() {
return new MethodDescription.ForLoadedMethod(SimpleCacheKey.class.getDeclaredMethod("of", Object[].class));
}
@Override
public InstrumentedType prepare(final InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public ByteCodeAppender appender(final Target implementationTarget) {
final TypeDescription thisType = implementationTarget.getInstrumentedType();
return new ByteCodeAppender.Simple(Arrays.asList(
// first param
MethodVariableAccess.loadThis(),
this.getField(thisType, "someField"),
// second param
MethodVariableAccess.loadThis(),
this.getField(thisType, "otherField"),
// call of and return the result
MethodInvocation.invoke(SIMPLE_CACHE_KEY_OF),
MethodReturn.of(TypeDescription.STRING)
));
}
private StackManipulation getField(final TypeDescription thisType, final String name) {
return FieldAccess.forField(thisType.getDeclaredFields()
.filter(ElementMatchers.named(name))
.getOnly()
).read();
}
}
Однако сгенерированный код выглядит следующим образом (декомпилирован с Intellij Idea):
public String getCacheKey() {
String var10000 = this.name;
return SimpleCacheKey.of(this.someValue);
}
Изменение подписи SimpleCacheKey.of
и попытка обойти проблему с List
не вариант.