@@ -60,6 +60,8 @@ public class InteropNodesProcessor extends BaseProcessor {
6060 private static final String GENERATE_INTEROP_NODES = "com.oracle.truffle.espresso.runtime.dispatch.messages.GenerateInteropNodes" ;
6161 private static final String EXPORT_MESSAGE = "com.oracle.truffle.api.library.ExportMessage" ;
6262
63+ private static final String EXPORT_REPEAT_MESSAGE = "com.oracle.truffle.api.library.ExportMessage.Repeat" ;
64+
6365 private static final String COLLECT = "com.oracle.truffle.espresso.substitutions.Collect" ;
6466 private static final String SPECIALIZATION = "com.oracle.truffle.api.dsl.Specialization" ;
6567 private static final String CACHED = "com.oracle.truffle.api.dsl.Cached" ;
@@ -83,6 +85,8 @@ public class InteropNodesProcessor extends BaseProcessor {
8385 private TypeElement generateInteropNodes ;
8486 // @ExportMessage
8587 private TypeElement exportMessage ;
88+
89+ private TypeElement exportRepeatMessage ;
8690 // @Shareable
8791 private TypeElement shareable ;
8892 // @Cached
@@ -102,6 +106,7 @@ public class InteropNodesProcessor extends BaseProcessor {
102106 private void collectAndCheckRequiredAnnotations () {
103107 generateInteropNodes = getTypeElement (GENERATE_INTEROP_NODES );
104108 exportMessage = getTypeElement (EXPORT_MESSAGE );
109+ exportRepeatMessage = getTypeElement (EXPORT_REPEAT_MESSAGE );
105110 shareable = getTypeElement (SHAREABLE );
106111 cached = getTypeElement (CACHED );
107112 cachedLibrary = getTypeElement (CACHED_LIBRARY );
@@ -153,17 +158,18 @@ private void processElement(TypeElement cls) {
153158 boolean shareableCls = isShareable (cls , false );
154159 List <Message > nodes = new ArrayList <>();
155160 for (Element methodElement : cls .getEnclosedElements ()) {
156- List <AnnotationMirror > exportedMethods = getAnnotations (methodElement , exportMessage .asType ());
157- // Look for exported messages. Note that a single method can export multiple message.
158- // Create one node per export.
161+ List <AnnotationMirror > exportedMethods = getAnnotations (methodElement , exportMessage .asType (), exportRepeatMessage .asType ());
162+ // Look for exported messages. Create one node per export.
159163 for (AnnotationMirror exportAnnotation : exportedMethods ) {
160- String targetMessageName = getAnnotationValue (exportAnnotation , "name" , String .class );
161- if (targetMessageName == null || targetMessageName . length () == 0 ) {
162- targetMessageName = methodElement .getSimpleName ().toString ();
164+ String exportedMessageName = getAnnotationValue (exportAnnotation , "name" , String .class );
165+ if (exportedMessageName == null || exportedMessageName . isEmpty () ) {
166+ exportedMessageName = methodElement .getSimpleName ().toString ();
163167 }
164- String clsName = ProcessorUtils .capitalize (methodElement .getSimpleName ().toString ()) + "Node" ;
168+ String capitalizedMessageName = ProcessorUtils .capitalize (exportedMessageName );
169+ String clsName = capitalizedMessageName + "Node" ;
165170 boolean isShareable = isShareable (methodElement , shareableCls );
166- nodes .add (new Message (processInteropNode (cls , (ExecutableElement ) methodElement , targetMessageName , clsName , imports ), targetMessageName , clsName , isShareable ));
171+ nodes .add (new Message (processInteropNode (cls , (ExecutableElement ) methodElement , exportedMessageName , clsName , imports ),
172+ capitalizedMessageName , clsName , isShareable ));
167173 }
168174 }
169175
@@ -197,7 +203,7 @@ private void processElement(TypeElement cls) {
197203
198204 // For all messages, add a line in registerMessages, and create the corresponding class
199205 for (Message m : nodes ) {
200- registerMessages .addBodyLine (INTEROP_MESSAGE_FACTORIES , ".register(cls, " , INTEROP_MESSAGE_MESSAGE , "." , ProcessorUtils . capitalize ( m .targetMessage ) , ", " , FACTORY_FIELD_NAME , "," ,
206+ registerMessages .addBodyLine (INTEROP_MESSAGE_FACTORIES , ".register(cls, " , INTEROP_MESSAGE_MESSAGE , "." , m .targetMessage , ", " , FACTORY_FIELD_NAME , "," ,
201207 m .isShareable , ");" );
202208 nodesClass .withInnerClass (m .cls );
203209 }
@@ -256,7 +262,7 @@ final InteropMessage create(InteropMessage.Message message) {
256262 createMethod .addBodyLine ("switch (message) {" );
257263 String clsName = sourceDispatch .getSimpleName ().toString () + ADDED_CLASS_SUFFIX ;
258264 for (Message m : nodes ) {
259- String targetMessageEnum = ProcessorUtils . capitalize ( m .targetMessage ) ;
265+ String targetMessageEnum = m .targetMessage ;
260266 String targetMessageImpl = clsName + "Factory." + m .clsName + "Gen" ;
261267 createMethod .addIndentedBodyLine (1 , "case " , targetMessageEnum , ": return " , targetMessageImpl , ".create();" );
262268 }
@@ -278,19 +284,20 @@ final InteropMessage create(InteropMessage.Message message) {
278284 return classBuilder ;
279285 }
280286
281- private ClassBuilder processInteropNode (TypeElement processingClass , ExecutableElement element , String targetMessageName , String clsName , Imports imports ) {
282- /*- abstract static class [MessageName]Node extends InteropMessage.[messageName] */
287+ private ClassBuilder processInteropNode (TypeElement processingClass , ExecutableElement element , String exportedMessageName , String clsName , Imports imports ) {
288+ String targetMethodName = element .getSimpleName ().toString ();
289+ /*- abstract static class [exportedMessageName]Node extends InteropMessage.[exportedMessageName] */
283290 ClassBuilder result = new ClassBuilder (clsName ) //
284291 .withQualifiers (new ModifierBuilder ().asStatic ().asAbstract ()) //
285- .withSuperClass (INTEROP_MESSAGE + "." + ProcessorUtils .capitalize (targetMessageName ));
292+ .withSuperClass (INTEROP_MESSAGE + "." + ProcessorUtils .capitalize (exportedMessageName ));
286293
287294 /*-
288295 @Specialization
289- static [returnType] [messageName ]([signature]) throws [thrownExceptions] {
290- [return] [processingClass].[messageName ]([args]);
296+ static [returnType] [exportedMessageName ]([signature]) throws [thrownExceptions] {
297+ [return] [processingClass].[targetMethodName ]([args]);
291298 }
292299 */
293- MethodBuilder m = new MethodBuilder (targetMessageName ) //
300+ MethodBuilder m = new MethodBuilder (exportedMessageName ) //
294301 .withAnnotation (new AnnotationBuilder (SPECIALIZATION ).withLineBreak ()) //
295302 .withModifiers (new ModifierBuilder ().asStatic ()) //
296303 .withReturnType (element .getReturnType ().toString ());
@@ -342,7 +349,7 @@ private ClassBuilder processInteropNode(TypeElement processingClass, ExecutableE
342349 }
343350 m .withSignature (declaredSig );
344351 String returnOrEmpty = element .getReturnType ().toString ().equals ("void" ) ? "" : "return " ;
345- m .addBodyLine (returnOrEmpty , processingClass .getQualifiedName (), "." , targetMessageName , invokeSig .toString (), ";" );
352+ m .addBodyLine (returnOrEmpty , processingClass .getQualifiedName (), "." , targetMethodName , invokeSig .toString (), ";" );
346353
347354 result .withMethod (m );
348355
0 commit comments