Skip to content

Commit 3340e64

Browse files
committed
[GR-69100] Automatically check for misplaced @UnknownPrimitiveField and @UnknownObjectField annotations
PullRequest: graal/21975
2 parents d006b4f + 5123c7f commit 3340e64

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/FieldValueInterceptionSupport.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
2424
*/
2525
package com.oracle.svm.hosted.ameta;
2626

27+
import java.lang.annotation.Annotation;
2728
import java.lang.reflect.Field;
2829
import java.util.ArrayList;
2930
import java.util.Arrays;
@@ -56,6 +57,7 @@
5657
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
5758
import com.oracle.svm.hosted.substitute.AutomaticUnsafeTransformationSupport;
5859
import com.oracle.svm.hosted.substitute.FieldValueTransformation;
60+
import com.oracle.svm.util.ClassUtil;
5961
import com.oracle.svm.util.ReflectionUtil;
6062

6163
import jdk.graal.compiler.nodes.ValueNode;
@@ -376,13 +378,15 @@ private static JavaConstant interceptWordField(AnalysisField field, JavaConstant
376378
private static FieldValueComputer createFieldValueComputer(AnalysisField field) {
377379
UnknownObjectField unknownObjectField = field.getAnnotation(UnknownObjectField.class);
378380
if (unknownObjectField != null) {
381+
checkMisplacedAnnotation(field.getStorageKind().isObject(), field);
379382
return new FieldValueComputer(
380383
ReflectionUtil.newInstance(unknownObjectField.availability()),
381384
extractAnnotationTypes(field, unknownObjectField.types(), unknownObjectField.fullyQualifiedTypes()),
382385
unknownObjectField.canBeNull());
383386
}
384387
UnknownPrimitiveField unknownPrimitiveField = field.getAnnotation(UnknownPrimitiveField.class);
385388
if (unknownPrimitiveField != null) {
389+
checkMisplacedAnnotation(field.getStorageKind().isPrimitive(), field);
386390
return new FieldValueComputer(
387391
ReflectionUtil.newInstance(unknownPrimitiveField.availability()),
388392
List.of(field.getType().getJavaClass()),
@@ -391,6 +395,31 @@ private static FieldValueComputer createFieldValueComputer(AnalysisField field)
391395
return null;
392396
}
393397

398+
/**
399+
* For compatibility reasons, we cannot unify {@link UnknownObjectField} and
400+
* {@link UnknownPrimitiveField} into a single annotation, but we can at least notify the
401+
* developers if the annotation is misplaced, e.g. {@link UnknownObjectField} is used on a
402+
* primitive field and vice versa.
403+
*/
404+
private static void checkMisplacedAnnotation(boolean condition, AnalysisField field) {
405+
if (!condition) {
406+
String fieldType;
407+
Class<? extends Annotation> expectedAnnotationType;
408+
Class<? extends Annotation> usedAnnotationType;
409+
if (field.getStorageKind().isObject()) {
410+
fieldType = "object";
411+
expectedAnnotationType = UnknownObjectField.class;
412+
usedAnnotationType = UnknownPrimitiveField.class;
413+
} else {
414+
fieldType = "primitive";
415+
expectedAnnotationType = UnknownPrimitiveField.class;
416+
usedAnnotationType = UnknownObjectField.class;
417+
}
418+
throw UserError.abort("@%s should not be used on %s fields, use @%s on %s instead.", ClassUtil.getUnqualifiedName(usedAnnotationType),
419+
fieldType, ClassUtil.getUnqualifiedName(expectedAnnotationType), field.format("%H.%n"));
420+
}
421+
}
422+
394423
private static List<Class<?>> extractAnnotationTypes(AnalysisField field, Class<?>[] types, String[] fullyQualifiedTypes) {
395424
List<Class<?>> annotationTypes = new ArrayList<>(Arrays.asList(types));
396425
for (String annotationTypeName : fullyQualifiedTypes) {

0 commit comments

Comments
 (0)