Make Builders sensitive to @Deprecated annotations 82/85082/3
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 12 Oct 2019 13:54:37 +0000 (15:54 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 17 Oct 2019 22:46:13 +0000 (00:46 +0200)
When we are generating a builder for a deprecated type, we need to
consider how it deals with deprecated elements.

There are two scenarios here:

1) status=deprecated -> @Deprecated
In this case it is fair game to produce data, hence the builder
is not deprecated and therefore has @SuppressWarnings("deprecation")

2) status=obsolete -> @Deprecated(forRemoval = true)
In this case the data should not be produced at all, hence
the builder needs to be @Deprecated(forRemoval), too.

We recognize both these conditions and act accordingly. We misue
bug-586 test case to hijack compilation testing.

JIRA: MDSAL-485
Change-Id: I9d08116615cf8c5bdb6a8f4977c9810686618cda
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/AbstractBuilderTemplate.xtend
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BaseTemplate.xtend
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderImplTemplate.xtend
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/BuilderTemplate.xtend
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/InterfaceTemplate.xtend
binding/mdsal-binding-java-api-generator/src/test/resources/compilation/bug586/foo.yang

index 8965a3b963a749ee657f0e957d04a5c9ee1c2489..da768ba22bc190f0747034737b4370f92d6693d3 100644 (file)
@@ -17,9 +17,11 @@ import java.util.Comparator
 import java.util.List
 import java.util.Map
 import java.util.Set
+import org.opendaylight.mdsal.binding.model.api.AnnotationType
 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject
 import org.opendaylight.mdsal.binding.model.api.GeneratedType
+import org.opendaylight.mdsal.binding.model.api.JavaTypeName
 import org.opendaylight.mdsal.binding.model.api.Type
 import org.opendaylight.mdsal.binding.model.util.Types
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping
@@ -29,6 +31,8 @@ import org.opendaylight.yangtools.yang.binding.Identifiable
 abstract class AbstractBuilderTemplate extends BaseTemplate {
     static val Comparator<GeneratedProperty> KEY_PROPS_COMPARATOR = [ p1, p2 | return p1.name.compareTo(p2.name) ]
 
+    protected static val DEPRECATED = JavaTypeName.create(Deprecated);
+
     /**
      * Generated property is set if among methods is found one with the name GET_AUGMENTATION_METHOD_NAME.
      */
@@ -146,9 +150,19 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
         }
     '''
 
+    def protected final CharSequence generateDeprecatedAnnotation(List<AnnotationType> annotations) {
+        var AnnotationType found = annotations.findDeprecatedAnnotation
+        if (found === null) {
+            return ""
+        }
+        return generateDeprecatedAnnotation(found)
+    }
+
     def protected abstract CharSequence generateCopyKeys(List<GeneratedProperty> keyProps)
 
-    def protected abstract CharSequence generateCopyAugmentation(Type implType);
+    def protected abstract CharSequence generateCopyAugmentation(Type implType)
+
+    def protected abstract CharSequence generateDeprecatedAnnotation(AnnotationType ann)
 
     private def boolean implementsIfc(GeneratedType type, Type impl) {
         for (Type ifc : type.implements) {
@@ -170,4 +184,15 @@ abstract class AbstractBuilderTemplate extends BaseTemplate {
             props.remove(toRemove);
         }
     }
+
+    private static def findDeprecatedAnnotation(List<AnnotationType> annotations) {
+        if (annotations !== null) {
+            for (annotation : annotations) {
+                if (DEPRECATED.equals(annotation.identifier)) {
+                    return annotation
+                }
+            }
+        }
+        return null
+    }
 }
index 967a8a4892c008037d7d6b5dba63f6430b4f33d3..6175c40b95c2a56f97398a2fd3893b1e875c12c0 100644 (file)
@@ -22,6 +22,7 @@ import java.util.Map.Entry
 import java.util.StringTokenizer
 import java.util.regex.Pattern
 import org.gaul.modernizer_maven_annotations.SuppressModernizer
+import org.opendaylight.mdsal.binding.model.api.AnnotationType
 import org.opendaylight.mdsal.binding.model.api.ConcreteType
 import org.opendaylight.mdsal.binding.model.api.Constant
 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
@@ -492,4 +493,15 @@ abstract class BaseTemplate extends JavaFileTemplate {
             result = prime * result + «property.importedUtilClass».hashCode(«property.fieldName»);
         «ENDFOR»
     '''
+
+    def protected final generateAnnotation(AnnotationType annotation) '''
+        @«annotation.importedName»
+        «IF annotation.parameters !== null && !annotation.parameters.empty»
+        (
+        «FOR param : annotation.parameters SEPARATOR ","»
+            «param.name»=«param.value»
+        «ENDFOR»
+        )
+        «ENDIF»
+    '''
 }
index 06fdcde916dd88d525bca3af0321ab7838f277bc..4f2a780623dcd92f89a494d7bb65eebd2a7d1953 100644 (file)
@@ -14,6 +14,7 @@ import static org.opendaylight.mdsal.binding.spec.naming.BindingMapping.DATA_CON
 import java.util.List
 import java.util.Map
 import java.util.Objects
+import org.opendaylight.mdsal.binding.model.api.AnnotationType
 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
 import org.opendaylight.mdsal.binding.model.api.GeneratedType
 import org.opendaylight.mdsal.binding.model.api.Type
@@ -31,6 +32,7 @@ class BuilderImplTemplate extends AbstractBuilderTemplate {
     }
 
     override body() '''
+        «targetType.annotations.generateDeprecatedAnnotation»
         private static final class «type.name»
             «val impIface = targetType.importedName»
             «IF augmentType !== null»
@@ -52,6 +54,10 @@ class BuilderImplTemplate extends AbstractBuilderTemplate {
         }
     '''
 
+    override generateDeprecatedAnnotation(AnnotationType ann) {
+        return generateAnnotation(ann)
+    }
+
     /**
      * Template method which generates the method <code>hashCode()</code>.
      *
index 632932286e113b99ab4236a3bc5d92649340ab85..3b5cc845cad4079550dc0e75cd4b6b62bbaedc27 100644 (file)
@@ -20,6 +20,7 @@ import java.util.List
 import java.util.Map
 import java.util.Set
 import java.util.regex.Pattern
+import org.opendaylight.mdsal.binding.model.api.AnnotationType
 import org.opendaylight.mdsal.binding.model.api.GeneratedProperty
 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject
 import org.opendaylight.mdsal.binding.model.api.GeneratedType
@@ -44,6 +45,7 @@ class BuilderTemplate extends AbstractBuilderTemplate {
     public static val BUILDER = "Builder";
 
     static val AUGMENTATION_FIELD_UPPER = AUGMENTATION_FIELD.toFirstUpper
+    static val SUPPRESS_WARNINGS = JavaTypeName.create(SuppressWarnings)
 
     /**
      * Constructs new instance of this class.
@@ -66,6 +68,7 @@ class BuilderTemplate extends AbstractBuilderTemplate {
      */
     override body() '''
         «wrapToDocumentation(formatDataForJavaDoc(targetType))»
+        «targetType.annotations.generateDeprecatedAnnotation»
         public class «type.name» implements «Builder.importedName»<«targetType.importedName»> {
 
             «generateFields(false)»
@@ -99,6 +102,14 @@ class BuilderTemplate extends AbstractBuilderTemplate {
         }
     '''
 
+    override generateDeprecatedAnnotation(AnnotationType ann) {
+        val forRemoval = ann.getParameter("forRemoval")
+        if (forRemoval !== null) {
+            return "@" + DEPRECATED.importedName + "(forRemoval = " + forRemoval.value + ")"
+        }
+        return "@" + SUPPRESS_WARNINGS.importedName + "(\"deprecation\")"
+    }
+
     /**
      * Generate default constructor and constructor for every implemented interface from uses statements.
      */
index a3d2c6c3d64b8e1e1876c33bdc1d88a1c6d6e83c..beb641eda62171307ba467eeeb738a7d257c77f1 100644 (file)
@@ -86,18 +86,10 @@ class InterfaceTemplate extends BaseTemplate {
 
     '''
 
-
     def private generateAnnotations(List<AnnotationType> annotations) '''
         «IF annotations !== null && !annotations.empty»
             «FOR annotation : annotations»
-                @«annotation.importedName»
-                «IF annotation.parameters !== null && !annotation.parameters.empty»
-                (
-                «FOR param : annotation.parameters SEPARATOR ","»
-                    «param.name»=«param.value»
-                «ENDFOR»
-                )
-                «ENDIF»
+                «annotation.generateAnnotation»
             «ENDFOR»
         «ENDIF»
     '''
index fcf4891a327cac849769b5f3c0ebe260937cc7d3..679f41004c70bbeabfcd5431ce78fadf2bde9185 100644 (file)
@@ -15,7 +15,9 @@ module foo {
 
 
     container services {
+        status deprecated;
         list service {
+            status obsolete;
             key "permission";
 
             leaf permission {