|
44 | 44 | import com.oracle.graal.python.annotations.ArgumentClinic.PrimitiveType;
|
45 | 45 | import com.oracle.graal.python.annotations.ArgumentClinic.ConversionFactory.ClinicArgument;
|
46 | 46 |
|
| 47 | +import javax.lang.model.element.Element; |
| 48 | +import javax.lang.model.element.ElementKind; |
47 | 49 | import javax.lang.model.element.ExecutableElement;
|
| 50 | +import javax.lang.model.element.Modifier; |
| 51 | +import javax.lang.model.element.TypeElement; |
| 52 | +import java.util.HashMap; |
| 53 | +import java.util.Map; |
48 | 54 |
|
49 | 55 | public class ConverterFactory {
|
50 | 56 | public static final String CLINIC_PACKAGE = "com.oracle.graal.python.nodes.function.builtins.clinic";
|
51 | 57 |
|
| 58 | + private static final Map<TypeElement, ConverterFactory> cache = new HashMap<>(); |
| 59 | + |
52 | 60 | public final String fullClassName;
|
53 | 61 | public final String className;
|
54 | 62 | public final String methodName;
|
55 | 63 | public final int paramCount;
|
56 | 64 | public final ClinicArgument[] clinicArgs;
|
57 | 65 | public final PrimitiveType[] acceptedPrimitiveTypes;
|
58 | 66 |
|
59 |
| - public ConverterFactory(ExecutableElement method, ClinicArgument[] clinicArgs) { |
| 67 | + private ConverterFactory(ExecutableElement method, ClinicArgument[] clinicArgs) { |
60 | 68 | fullClassName = method.getEnclosingElement().toString();
|
61 | 69 | className = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
|
62 | 70 | methodName = method.getSimpleName().toString();
|
@@ -127,4 +135,29 @@ public static ConverterFactory getBuiltin(ArgumentClinic annotation) {
|
127 | 135 | throw new IllegalArgumentException(annotation.conversion().toString());
|
128 | 136 | }
|
129 | 137 | }
|
| 138 | + |
| 139 | + public static ConverterFactory getForClass(TypeElement conversionClass) throws ProcessingError { |
| 140 | + ConverterFactory factory = cache.get(conversionClass); |
| 141 | + if (factory != null) { |
| 142 | + return factory; |
| 143 | + } |
| 144 | + for (Element e : conversionClass.getEnclosedElements()) { |
| 145 | + ArgumentClinic.ConversionFactory annot = e.getAnnotation(ArgumentClinic.ConversionFactory.class); |
| 146 | + if (annot != null) { |
| 147 | + if (!e.getModifiers().contains(Modifier.STATIC) || e.getKind() != ElementKind.METHOD) { |
| 148 | + throw new ProcessingError(conversionClass, "ConversionFactory annotation is applicable only to static methods."); |
| 149 | + } |
| 150 | + if (factory != null) { |
| 151 | + throw new ProcessingError(conversionClass, "Multiple ConversionFactory annotations in a single class."); |
| 152 | + } |
| 153 | + factory = new ConverterFactory((ExecutableElement) e, annot.clinicArgs()); |
| 154 | + } |
| 155 | + } |
| 156 | + if (factory == null) { |
| 157 | + throw new ProcessingError(conversionClass, "No ConversionFactory annotation found."); |
| 158 | + } |
| 159 | + cache.put(conversionClass, factory); |
| 160 | + return factory; |
| 161 | + } |
| 162 | + |
130 | 163 | }
|
0 commit comments