eclipse-xtext / eclipse-xtext/xtext

Generator of repeatable active annotations on fields is called too often

Open
#1,441 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
831
Forks
330
Avg merge
3d 7h
Merged PRs (30d)
12

Description

Minimal example based on projects xtend-annotations-examples and xtend-annotations-examples-client created with project wizard "Xtend > Examples > Xtend Active Annotation Examples":

  1. Add a new package called "repeatable" to both projects.
  2. Add this Xtend class to first project in package repeatable:
package repeatable

import java.lang.annotation.Target
import java.lang.annotation.ElementType
import java.lang.annotation.Repeatable
import org.eclipse.xtend.lib.macro.Active
import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration
import org.eclipse.xtend.lib.macro.AbstractFieldProcessor
import org.eclipse.xtend.lib.macro.TransformationContext
import org.eclipse.xtend.lib.macro.declaration.AnnotationTarget
import org.eclipse.xtend.lib.macro.declaration.AnnotationReference
import org.eclipse.xtend.lib.annotations.Accessors

@Target(ElementType.FIELD)
@Repeatable(MyAnnos)
@Active(MyAnnoProcessor)
annotation MyAnno {
	int group = 0
}

@Target(ElementType.FIELD)
annotation MyAnnos {
	MyAnno[] value
}

class MyAnnoProcessor extends AbstractFieldProcessor {

	extension AnnotationExtensions = new AnnotationExtensions

	override doTransform(MutableFieldDeclaration field, extension TransformationContext context) {

		var annos = field.getAnnotations(context)
		for (anno : annos) {
			doTransformSingleAnnotation(anno, field, context)
		}
	}

	def doTransformSingleAnnotation(AnnotationReference annoRef, MutableFieldDeclaration field,
		extension TransformationContext context) {
		val group = annoRef.getValue("group") as Integer

		field.declaringType.addMethod("method" + group) [
			returnType = context.primitiveVoid
			body = ''''''
		]
	}

	private def getAnnotations(MutableFieldDeclaration field, extension TransformationContext context) {
		findAnnotations(
			new AnnotationSearch => [
				it.type = field
				it.context = context
				it.annotationClass = MyAnno
			],
			context
		)
	}
}

class AnnotationExtensions {

	def findAnnotations(extension AnnotationSearch annotationSearch, extension TransformationContext context) {
		type.annotations.filter [
			annotationTypeDeclaration.qualifiedName == annotationClass.newTypeReference.type.qualifiedName
		]
	}
}

class AnnotationSearch {
	@Accessors AnnotationTarget type
	@Accessors TransformationContext context
	@Accessors Class<?> annotationClass
}
  1. Add this code to package repeatable in second project (client):
package repeatable

class RepeatableExample {
	
	@MyAnno(group=0)
	@MyAnno(group=1)
	@MyAnno(group=2)
	String field
}

To see the active annotation in client-project you have to extend the MANIFEST.MF of the first project with the package repeatable as exported.

And following code is generated:

package repeatable;

import repeatable.MyAnno;

@SuppressWarnings("all")
public class RepeatableExample {
  @MyAnno(group = 0)
  @MyAnno(group = 1)
  @MyAnno(group = 2)
  private String field;
  
  public void method0() {
  }
  public void method1() {
  }
  public void method2() {
  }
  public void method0() {
  }
  public void method1() {
  }
  public void method2() {
  }
  public void method0() {
  }
  public void method1() {
  }
  public void method2() {
  }
}

So the field generation is called too often.

https://www.eclipse.org/forums/index.php/t/1098725/

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Recreate the two projects with the Xtend Examples wizard, add the repeatable package and the supplied MyAnnoProcessor and RepeatableExample sources, and export repeatable in MANIFEST.MF. Compare the generated RepeatableExample output with the example: each annotation should produce method0, method1, and method2 only once.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
compilers, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.