package com.oracle.svm.hosted.substitute;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import com.oracle.graal.pointsto.infrastructure.OriginalFieldProvider;
import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.annotate.InjectAccessors;
import com.oracle.svm.core.meta.ReadableJavaField;
import com.oracle.svm.hosted.c.GraalAccess;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
public class AnnotatedField implements ReadableJavaField, OriginalFieldProvider {
static Annotation[] appendAnnotationTo(Annotation[] array, Annotation element) {
Annotation[] result = Arrays.copyOf(array, array.length + 1);
result[result.length - 1] = element;
return result;
}
private final ResolvedJavaField original;
private final Annotation injectedAnnotation;
public AnnotatedField(ResolvedJavaField original, Annotation injectedAnnotation) {
this.original = original;
this.injectedAnnotation = injectedAnnotation;
}
@Override
public Annotation[] getAnnotations() {
return appendAnnotationTo(original.getAnnotations(), injectedAnnotation);
}
@Override
public Annotation[] getDeclaredAnnotations() {
return appendAnnotationTo(original.getDeclaredAnnotations(), injectedAnnotation);
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (annotationClass.isInstance(injectedAnnotation)) {
return annotationClass.cast(injectedAnnotation);
}
return original.getAnnotation(annotationClass);
}
@Override
public JavaConstant readValue(JavaConstant receiver) {
return ReadableJavaField.readFieldValue(GraalAccess.getOriginalProviders().getConstantReflection(), original, receiver);
}
@Override
public boolean allowConstantFolding() {
assert (injectedAnnotation instanceof Delete) || (injectedAnnotation instanceof InjectAccessors) : "Unknown annotation @" +
injectedAnnotation.annotationType().getSimpleName() + ", should constant folding be permitted?";
return false;
}
@Override
public boolean injectFinalForRuntimeCompilation() {
return ReadableJavaField.injectFinalForRuntimeCompilation(original);
}
@Override
public String getName() {
return original.getName();
}
@Override
public JavaType getType() {
return original.getType();
}
@Override
public int getModifiers() {
return original.getModifiers();
}
@Override
public int getOffset() {
return original.getOffset();
}
@Override
public boolean isInternal() {
return original.isInternal();
}
@Override
public boolean isSynthetic() {
return original.isSynthetic();
}
@Override
public ResolvedJavaType getDeclaringClass() {
return original.getDeclaringClass();
}
@Override
public String toString() {
return "InjectedAnnotationField<original " + original.toString() + ", annotation: " + injectedAnnotation + ">";
}
@Override
public Field getJavaField() {
return OriginalFieldProvider.getJavaField(GraalAccess.getOriginalSnippetReflection(), original);
}
}