Respect @Repeatable property of Annotations in the Xtext Generator. Fixes #270

Signed-off-by: Christian Dietrich <christian.dietrich@itemis.de>
This commit is contained in:
Christian Dietrich 2017-02-03 09:35:55 +01:00
parent 945301f598
commit b5055c9aff
11 changed files with 76 additions and 7 deletions

View file

@ -8,6 +8,7 @@
package org.eclipse.xtext.xtext.generator
import com.google.inject.Injector
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.Date
import java.util.List
@ -15,7 +16,6 @@ import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtext.util.Strings
import org.eclipse.xtext.util.XtextVersion
import org.eclipse.xtext.xtext.generator.model.annotations.IClassAnnotation
import java.nio.charset.Charset
/**
* Configuration object for generated code.

View file

@ -4,7 +4,6 @@ import java.util.List
import org.eclipse.xtend.lib.annotations.Accessors
import org.eclipse.xtend2.lib.StringConcatenationClient
import org.eclipse.xtext.xtext.generator.CodeConfig
import org.eclipse.xtext.xtext.generator.model.JavaFileAccess.JavaTypeAwareStringConcatenation
import org.eclipse.xtext.xtext.generator.model.annotations.IClassAnnotation
/**
@ -49,7 +48,7 @@ class GeneratedJavaFileAccess extends JavaFileAccess {
}
private def getClassAnnotations() {
annotations + codeConfig.classAnnotations.filter[appliesTo(this)]
(annotations + codeConfig.classAnnotations.filter[appliesTo(this)]).toSet
}
override getInternalContent() '''

View file

@ -69,5 +69,13 @@ class GeneratedClassAnnotation implements IClassAnnotation {
override toString() {
generate.toString
}
override equals(Object obj) {
return obj instanceof GeneratedClassAnnotation
}
override hashCode() {
return class.name.hashCode;
}
}

View file

@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.xtext.xtext.generator.model.annotations
import java.lang.annotation.Repeatable
import org.eclipse.xtext.xtext.generator.XtextGenerator
import org.eclipse.xtext.xtext.generator.model.JavaFileAccess
import org.eclipse.xtext.xtext.generator.model.TypeReference
@ -14,6 +15,12 @@ import org.eclipse.xtext.xtext.generator.model.TypeReference
/**
* Class annotations can be added to the {@link XtextGenerator} workflow component in order
* to configure specific Java annotations to be added to each generated class.
* <br/><br/>
* Make sure that you implement {@link Object#equals(Object)} and {@link Object#hashCode()} to fulfill following contract
* <ul>
* <li>If the underlying Annotation is {@link Repeatable} then the methods should behave like in {@link Object}.</li>
* <li>If the underlying Annotation is NOT {@link Repeatable} then {@link Object#equals(Object)} should return true for all instances and {@link Object#hashCode()} should return the same value for all instances</li>
* </ul>
*/
interface IClassAnnotation {

View file

@ -31,4 +31,12 @@ class SingletonClassAnnotation implements IClassAnnotation {
override toString() {
generate.toString
}
override equals(Object obj) {
return obj instanceof SingletonClassAnnotation
}
override hashCode() {
return class.name.hashCode;
}
}

View file

@ -41,5 +41,14 @@ class SuppressWarningsAnnotation implements IClassAnnotation {
override toString() {
generate.toString
}
}
override equals(Object obj) {
return obj instanceof SuppressWarningsAnnotation
}
override hashCode() {
return class.name.hashCode;
}
}

View file

@ -2,6 +2,7 @@ package org.eclipse.xtext.xtext.generator.model;
import com.google.common.collect.Iterables;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtend2.lib.StringConcatenation;
@ -65,12 +66,12 @@ public class GeneratedJavaFileAccess extends JavaFileAccess {
return _xblockexpression;
}
private Iterable<IClassAnnotation> getClassAnnotations() {
private Set<IClassAnnotation> getClassAnnotations() {
final Function1<IClassAnnotation, Boolean> _function = (IClassAnnotation it) -> {
return Boolean.valueOf(it.appliesTo(this));
};
Iterable<IClassAnnotation> _filter = IterableExtensions.<IClassAnnotation>filter(this.codeConfig.getClassAnnotations(), _function);
return Iterables.<IClassAnnotation>concat(this.annotations, _filter);
return IterableExtensions.<IClassAnnotation>toSet(Iterables.<IClassAnnotation>concat(this.annotations, _filter));
}
@Override
@ -79,7 +80,7 @@ public class GeneratedJavaFileAccess extends JavaFileAccess {
_builder.append(this.typeComment);
_builder.newLineIfNotEmpty();
{
Iterable<IClassAnnotation> _classAnnotations = this.getClassAnnotations();
Set<IClassAnnotation> _classAnnotations = this.getClassAnnotations();
for(final IClassAnnotation annot : _classAnnotations) {
CharSequence _generate = annot.generate();
_builder.append(_generate);

View file

@ -80,6 +80,16 @@ public class GeneratedClassAnnotation implements IClassAnnotation {
return this.generate().toString();
}
@Override
public boolean equals(final Object obj) {
return (obj instanceof GeneratedClassAnnotation);
}
@Override
public int hashCode() {
return this.getClass().getName().hashCode();
}
@Pure
public boolean isIncludeDate() {
return this.includeDate;

View file

@ -7,6 +7,7 @@
*/
package org.eclipse.xtext.xtext.generator.model.annotations;
import java.lang.annotation.Repeatable;
import org.eclipse.xtext.xtext.generator.XtextGenerator;
import org.eclipse.xtext.xtext.generator.model.JavaFileAccess;
import org.eclipse.xtext.xtext.generator.model.TypeReference;
@ -14,6 +15,12 @@ import org.eclipse.xtext.xtext.generator.model.TypeReference;
/**
* Class annotations can be added to the {@link XtextGenerator} workflow component in order
* to configure specific Java annotations to be added to each generated class.
* <br/><br/>
* Make sure that you implement {@link Object#equals(Object)} and {@link Object#hashCode()} to fulfill following contract
* <ul>
* <li>If the underlying Annotation is {@link Repeatable} then the methods should behave like in {@link Object}.</li>
* <li>If the underlying Annotation is NOT {@link Repeatable} then {@link Object#equals(Object)} should return true for all instances and {@link Object#hashCode()} should return the same value for all instances</li>
* </ul>
*/
@SuppressWarnings("all")
public interface IClassAnnotation {

View file

@ -36,4 +36,14 @@ public class SingletonClassAnnotation implements IClassAnnotation {
public String toString() {
return this.generate().toString();
}
@Override
public boolean equals(final Object obj) {
return (obj instanceof SingletonClassAnnotation);
}
@Override
public int hashCode() {
return this.getClass().getName().hashCode();
}
}

View file

@ -61,6 +61,16 @@ public class SuppressWarningsAnnotation implements IClassAnnotation {
return this.generate().toString();
}
@Override
public boolean equals(final Object obj) {
return (obj instanceof SuppressWarningsAnnotation);
}
@Override
public int hashCode() {
return this.getClass().getName().hashCode();
}
@Pure
public String getSuppress() {
return this.suppress;