1
1
/*
2
- * Copyright (c) 2024, 2024 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2024, 2025 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* The Universal Permissive License (UPL), Version 1.0
63
63
import javax .tools .Diagnostic .Kind ;
64
64
import javax .tools .JavaFileObject ;
65
65
66
+ import com .oracle .graal .python .annotations .HashNotImplemented ;
66
67
import com .oracle .graal .python .annotations .Slot ;
67
68
import com .oracle .graal .python .annotations .Slot .SlotKind ;
68
69
import com .oracle .graal .python .annotations .Slot .Slots ;
@@ -72,11 +73,27 @@ public class SlotsProcessor extends AbstractProcessor {
72
73
private static final boolean LOGGING = false ;
73
74
74
75
public record TpSlotData (Slot slot , TypeElement enclosingType , TypeElement slotNodeType ) {
76
+ public boolean isHashNotImplemented () {
77
+ return slotNodeType == null ;
78
+ }
79
+
80
+ public static TpSlotData createHashNotImplemented (TypeElement enclosingType ) {
81
+ return new TpSlotData (null , enclosingType , null );
82
+ }
83
+
84
+ public String builderCall () {
85
+ if (isHashNotImplemented ()) {
86
+ return ".set(TpSlots.TpSlotMeta.TP_HASH, com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HASH_NOT_IMPLEMENTED)" ;
87
+ }
88
+ return String .format (".set(TpSlots.TpSlotMeta.%s, %s.INSTANCE)" , //
89
+ slot .value ().name ().toUpperCase (Locale .ROOT ), //
90
+ getSlotImplName (slot .value ()));
91
+ }
75
92
}
76
93
77
94
@ Override
78
95
public Set <String > getSupportedAnnotationTypes () {
79
- return Set .of (Slot .class .getName ());
96
+ return Set .of (Slot .class .getName (), HashNotImplemented . class . getName () );
80
97
}
81
98
82
99
@ Override
@@ -109,7 +126,14 @@ private void doProcess(RoundEnvironment roundEnv) throws IOException, Processing
109
126
private void validate (HashMap <TypeElement , Set <TpSlotData >> enclosingTypes ) throws ProcessingError {
110
127
var typeCache = new TypeCache (processingEnv );
111
128
for (Entry <TypeElement , Set <TpSlotData >> enclosingType : enclosingTypes .entrySet ()) {
129
+ boolean seenHashNotImplemented = false ;
130
+ boolean seenHash = false ;
112
131
for (TpSlotData slot : enclosingType .getValue ()) {
132
+ if (slot .isHashNotImplemented ()) {
133
+ seenHashNotImplemented = true ;
134
+ continue ;
135
+ }
136
+ seenHash |= slot .slot .value () == SlotKind .tp_hash ;
113
137
if (slot .slot .isComplex ()) {
114
138
if (!SlotsMapping .supportsComplex (slot .slot ().value ())) {
115
139
throw error (slot .slotNodeType , "Slot does not support complex builtins. The support can be added." );
@@ -125,14 +149,22 @@ private void validate(HashMap<TypeElement, Set<TpSlotData>> enclosingTypes) thro
125
149
throw error (slot .slotNodeType , "Slot does not inherit from expected base class '%s'" , baseName );
126
150
}
127
151
}
152
+ if (seenHash && seenHashNotImplemented ) {
153
+ throw error (enclosingType .getKey (), "Annotation %s cannot be use when there is also %s(tp_hash). Remove one or the other." ,
154
+ HashNotImplemented .class .getSimpleName (),
155
+ Slot .class .getSimpleName ());
156
+ }
128
157
}
129
158
}
130
159
131
160
@ SuppressWarnings ("try" )
132
161
private void writeCode (HashMap <TypeElement , Set <TpSlotData >> enclosingTypes ) throws IOException {
133
- for (Entry <TypeElement , Set <TpSlotData >> enclosingType : enclosingTypes .entrySet ()) {
134
- String pkgName = getPackage (enclosingType .getKey ());
135
- String className = enclosingType .getKey ().getSimpleName () + "SlotsGen" ;
162
+ for (Entry <TypeElement , Set <TpSlotData >> enclosingTypeAndSlots : enclosingTypes .entrySet ()) {
163
+ Set <TpSlotData > slots = enclosingTypeAndSlots .getValue ();
164
+ TypeElement enclosingType = enclosingTypeAndSlots .getKey ();
165
+
166
+ String pkgName = getPackage (enclosingType );
167
+ String className = enclosingType .getSimpleName () + "SlotsGen" ;
136
168
String sourceFile = pkgName + "." + className ;
137
169
log ("Generating file '%s'" , sourceFile );
138
170
@@ -146,10 +178,10 @@ private void writeCode(HashMap<TypeElement, Set<TpSlotData>> enclosingTypes) thr
146
178
w .writeLn ();
147
179
w .writeLn ("public class %s {" , className );
148
180
try (Block i = w .newIndent ()) {
149
- for (TpSlotData slot : enclosingType . getValue () ) {
181
+ for (TpSlotData slot : slots ) {
150
182
writeSlot (w , slot );
151
183
}
152
- writeSlotsStaticField (w , enclosingType . getValue () );
184
+ writeSlotsStaticField (w , enclosingType , slots );
153
185
}
154
186
w .writeLn ("}" );
155
187
}
@@ -168,6 +200,9 @@ private void writeImports(CodeWriter w) throws IOException {
168
200
169
201
@ SuppressWarnings ("try" )
170
202
private void writeSlot (CodeWriter w , TpSlotData slot ) throws IOException {
203
+ if (slot .isHashNotImplemented ()) {
204
+ return ;
205
+ }
171
206
log ("Writing slot node %s" , slot .slotNodeType );
172
207
String slotImplName = getSlotImplName (slot .slot .value ());
173
208
String genericArg = "" ;
@@ -202,13 +237,11 @@ private void writeSlot(CodeWriter w, TpSlotData slot) throws IOException {
202
237
}
203
238
204
239
@ SuppressWarnings ("try" )
205
- private static void writeSlotsStaticField (CodeWriter w , Set <TpSlotData > slots ) throws IOException {
240
+ private static void writeSlotsStaticField (CodeWriter w , TypeElement enclosingType , Set <TpSlotData > slots ) throws IOException {
206
241
w .writeLn ("static final TpSlots SLOTS = TpSlots.newBuilder()" );
207
242
try (Block i3 = w .newIndent ()) {
208
243
String defs = slots .stream ().//
209
- map (s -> String .format (".set(TpSlots.TpSlotMeta.%s, %s.INSTANCE)" , //
210
- s .slot .value ().name ().toUpperCase (Locale .ROOT ), //
211
- getSlotImplName (s .slot .value ()))).//
244
+ map (TpSlotData ::builderCall ).//
212
245
collect (Collectors .joining ("\n " ));
213
246
w .writeLn ("%s." , defs );
214
247
w .writeLn ("build();" );
@@ -237,6 +270,12 @@ private HashMap<TypeElement, Set<TpSlotData>> collectEnclosingTypes(RoundEnviron
237
270
tpSlotDataSet .add (new TpSlotData (slotAnnotation , enclosingType , type ));
238
271
}
239
272
}
273
+ elements = new HashSet <>(roundEnv .getElementsAnnotatedWithAny (Set .of (HashNotImplemented .class )));
274
+ for (Element element : elements ) {
275
+ TypeElement typeElement = (TypeElement ) element ;
276
+ enclosingTypes .computeIfAbsent (typeElement , key -> new HashSet <>()).//
277
+ add (TpSlotData .createHashNotImplemented (typeElement ));
278
+ }
240
279
return enclosingTypes ;
241
280
}
242
281
0 commit comments