BUG-1347: fixed bug in generation constraints for decimal64 type. 25/8925/1
authorMartin Vitez <mvitez@cisco.com>
Thu, 10 Jul 2014 13:51:32 +0000 (15:51 +0200)
committerMartin Vitez <mvitez@cisco.com>
Fri, 11 Jul 2014 08:13:14 +0000 (10:13 +0200)
Added test.

Change-Id: I52a539ea7c5ff6b36b9bc362660188f9627bff7d
Signed-off-by: Martin Vitez <mvitez@cisco.com>
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java
code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang

index 672d4b648e94eea593dbd1d04a8d6415bcefa751..c1b1074d5d45b06e0db40be6181d250030ed27e0 100644 (file)
@@ -178,7 +178,7 @@ abstract class BaseTemplate {
                 «generateLengthRestriction(returnType, restrictions, paramName, isNestedType)»
             «ENDIF»
             «IF !restrictions.rangeConstraints.empty»
-                «generateRangeRestriction(returnType, restrictions, paramName, isNestedType)»
+                «generateRangeRestriction(returnType, paramName, isNestedType)»
             «ENDIF»
         «ENDIF»
     '''
@@ -199,12 +199,11 @@ abstract class BaseTemplate {
         }
     '''
 
-    def private generateRangeRestriction(Type returnType, Restrictions restrictions, String paramName, boolean isNestedType) '''
-        «val clazz = restrictions.rangeConstraints.iterator.next.min.class»
+    def private generateRangeRestriction(Type returnType, String paramName, boolean isNestedType) '''
         if («paramName» != null) {
-            «printRangeConstraint(returnType, clazz, paramName, isNestedType)»
+            «printRangeConstraint(returnType, paramName, isNestedType)»
             boolean isValidRange = false;
-            for («Range.importedName»<«clazz.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) {
+            for («Range.importedName»<«returnType.importedNumber»> r : «IF isNestedType»«returnType.importedName».«ENDIF»range()) {
                 if (r.contains(_constraint)) {
                     isValidRange = true;
                 }
@@ -223,22 +222,22 @@ abstract class BaseTemplate {
         «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»«IF isNestedType».getValue()«ENDIF».length«IF !isArray»()«ENDIF»);
     '''
 
-    def printRangeConstraint(Type returnType, Class<? extends Number> clazz, String paramName, boolean isNestedType) '''
-        «IF clazz.canonicalName.equals(BigDecimal.canonicalName)»
-            «clazz.importedNumber» _constraint = new «clazz.importedNumber»(«paramName»«IF isNestedType».getValue()«ENDIF».toString());
+    def printRangeConstraint(Type returnType, String paramName, boolean isNestedType) '''
+        «IF BigDecimal.canonicalName.equals(returnType.fullyQualifiedName)»
+            «BigDecimal.importedName» _constraint = new «BigDecimal.importedName»(«paramName»«IF isNestedType».getValue()«ENDIF».toString());
         «ELSE»
             «IF isNestedType»
                 «val propReturnType = findProperty(returnType as GeneratedTransferObject, "value").returnType»
                 «IF propReturnType.fullyQualifiedName.equals(BigInteger.canonicalName)»
-                    «clazz.importedNumber» _constraint = «paramName».getValue();
+                    «BigInteger.importedName» _constraint = «paramName».getValue();
                 «ELSE»
-                    «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName».getValue());
+                    «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName».getValue());
                 «ENDIF»
             «ELSE»
                 «IF returnType.fullyQualifiedName.equals(BigInteger.canonicalName)»
-                    «clazz.importedNumber» _constraint = «paramName»;
+                    «BigInteger.importedName» _constraint = «paramName»;
                 «ELSE»
-                    «clazz.importedNumber» _constraint = «clazz.importedNumber».valueOf(«paramName»);
+                    «BigInteger.importedName» _constraint = «BigInteger.importedName».valueOf(«paramName»);
                 «ENDIF»
             «ENDIF»
         «ENDIF»
@@ -271,15 +270,6 @@ abstract class BaseTemplate {
         «ENDIF»
     '''
 
-    def GeneratedProperty getPropByName(GeneratedType gt, String name) {
-        for (GeneratedProperty prop : gt.properties) {
-            if (prop.name.equals(name)) {
-                return prop;
-            }
-        }
-        return null;
-    }
-
     def getRestrictions(Type type) {
         var Restrictions restrictions = null
         if (type instanceof ConcreteType) {
@@ -347,15 +337,27 @@ abstract class BaseTemplate {
         return «varName»;
     '''
 
-    def protected generateRangeMethod(String methodName, Type type, String className, String varName) '''
-        «val Restrictions restrictions = type.restrictions»
+    def protected generateRangeMethod(String methodName, Restrictions restrictions, Type returnType, String className, String varName) '''
         «IF restrictions != null && !(restrictions.rangeConstraints.empty)»
-            «val numberClass = restrictions.rangeConstraints.iterator.next.min.class»
-            public static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> «methodName»() {
-                «IF numberClass.equals(typeof(BigDecimal))»
-                    «rangeMethodBody(restrictions, numberClass, className, varName)»
+            «val number = returnType.importedNumber»
+            public static «List.importedName»<«Range.importedName»<«number»>> «methodName»() {
+                «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
+                    «rangeMethodBody(restrictions, BigDecimal, className, varName)»
+                «ELSE»
+                    «rangeMethodBody(restrictions, BigInteger, className, varName)»
+                «ENDIF»
+            }
+        «ENDIF»
+    '''
+
+    def protected generateRangeMethod(String methodName, Restrictions restrictions, String className, String varName, Iterable<GeneratedProperty> properties) '''
+        «IF restrictions != null && !(restrictions.rangeConstraints.empty)»
+            «val returnType = properties.iterator.next.returnType»
+            public static «List.importedName»<«Range.importedName»<«returnType.importedNumber»>> «methodName»() {
+                «IF returnType.fullyQualifiedName.equals(BigDecimal.canonicalName)»
+                    «rangeMethodBody(restrictions, BigDecimal, className, varName)»
                 «ELSE»
-                    «rangeMethodBody(restrictions, typeof(BigInteger), className, varName)»
+                    «rangeMethodBody(restrictions, BigInteger, className, varName)»
                 «ENDIF»
             }
         «ENDIF»
@@ -383,6 +385,13 @@ abstract class BaseTemplate {
         return BigInteger.importedName
     }
 
+    def protected String importedNumber(Type clazz) {
+        if (clazz.fullyQualifiedName.equals(BigDecimal.canonicalName)) {
+            return BigDecimal.importedName
+        }
+        return BigInteger.importedName
+    }
+
     def private String numericValue(Class<? extends Number> clazz, Object numberValue) {
         val number = clazz.importedName;
         val value = numberValue.toString
index fbd198054a40310ecd6300ec79aa6e4c8af7f258..c97838ed02125b073a37d61ec53d00e2b72d5546 100644 (file)
@@ -405,12 +405,10 @@ class BuilderTemplate extends BaseTemplate {
                 «val restrictions = f.returnType.restrictions»
                 «IF !_final && restrictions != null»
                     «IF !(restrictions.lengthConstraints.empty)»
-                        «val clazz = restrictions.lengthConstraints.iterator.next.min.class»
-                        private static «List.importedName»<«Range.importedName»<«clazz.importedNumber»>> «f.fieldName»_length;
+                        private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_length;
                     «ENDIF»
                     «IF !(restrictions.rangeConstraints.empty)»
-                        «val clazz = restrictions.rangeConstraints.iterator.next.min.class»
-                        private static «List.importedName»<«Range.importedName»<«clazz.importedNumber»>> «f.fieldName»_range;
+                        private static «List.importedName»<«Range.importedName»<«f.returnType.importedNumber»>> «f.fieldName»_range;
                     «ENDIF»
                 «ENDIF»
             «ENDFOR»
@@ -438,7 +436,7 @@ class BuilderTemplate extends BaseTemplate {
                 return this;
             }
             «generateLengthMethod(length, field.returnType, type.name+BUILDER, length)»
-            «generateRangeMethod(range, field.returnType, type.name+BUILDER, range)»
+            «generateRangeMethod(range, field.returnType.restrictions, field.returnType, type.name+BUILDER, range)»
         «ENDFOR»
         «IF augmentField != null»
 
@@ -466,7 +464,7 @@ class BuilderTemplate extends BaseTemplate {
                 «generateLengthRestriction(type, paramName, lengthGetter, isNestedType, isArray)»
             «ENDIF»
             «IF !restrictions.rangeConstraints.empty»
-                «generateRangeRestriction(type, paramName, rangeGetter, isNestedType, isArray
+                «generateRangeRestriction(type, paramName, rangeGetter, isNestedType)»
             «ENDIF»
         «ENDIF»
     '''
@@ -488,13 +486,11 @@ class BuilderTemplate extends BaseTemplate {
         }
     '''
 
-    def private generateRangeRestriction(Type type, String paramName, String getterName, boolean isNestedType, boolean isArray) '''
-        «val restrictions = type.getRestrictions»
+    def private generateRangeRestriction(Type type, String paramName, String getterName, boolean isNestedType) '''
         if («paramName» != null) {
-            «val clazz = restrictions.rangeConstraints.iterator.next.min.class»
-            «printRangeConstraint(type, clazz, paramName, isNestedType)»
+            «printRangeConstraint(type, paramName, isNestedType)»
             boolean isValidRange = false;
-            for («Range.importedName»<«clazz.importedNumber»> r : «getterName»()) {
+            for («Range.importedName»<«type.importedNumber»> r : «getterName»()) {
                 if (r.contains(_constraint)) {
                     isValidRange = true;
                 }
index 85b2df5d6243ad2f765ffae0943d1e91a8203f9e..fed70f50ea5beb0a2b7709694f2c557650be7877 100644 (file)
@@ -127,7 +127,7 @@ class ClassTemplate extends BaseTemplate {
 
             «generateLengthMethod("length", genTO, genTO.importedName, "_length")»
 
-            «generateRangeMethod("range", genTO, genTO.importedName, "_range"
+            «generateRangeMethod("range", genTO.restrictions, genTO.importedName, "_range", allProperties
 
         }
     '''
@@ -366,13 +366,15 @@ class ClassTemplate extends BaseTemplate {
      */
     def protected generateFields() '''
         «IF restrictions != null»
-            «IF !(restrictions.lengthConstraints.empty)»
-                «val numberClass = restrictions.lengthConstraints.iterator.next.min.class»
-                private static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> _length;
-            «ENDIF»
-            «IF !(restrictions.rangeConstraints.empty)»
-                «val numberClass = restrictions.rangeConstraints.iterator.next.min.class»
-                private static «List.importedName»<«Range.importedName»<«numberClass.importedNumber»>> _range;
+            «val prop = getPropByName("value")»
+            «IF prop != null»
+                «val numberClass = prop.returnType.importedNumber»
+                «IF !(restrictions.lengthConstraints.empty)»
+                    private static «List.importedName»<«Range.importedName»<«numberClass»>> _length;
+                «ENDIF»
+                «IF !(restrictions.rangeConstraints.empty)»
+                    private static «List.importedName»<«Range.importedName»<«numberClass»>> _range;
+                «ENDIF»
             «ENDIF»
         «ENDIF»
         «IF !properties.empty»
@@ -444,4 +446,13 @@ class ClassTemplate extends BaseTemplate {
         «ENDIF»
     '''
 
+    def GeneratedProperty getPropByName(String name) {
+        for (GeneratedProperty prop : allProperties) {
+            if (prop.name.equals(name)) {
+                return prop;
+            }
+        }
+        return null;
+    }
+
 }
index f8b2eda1a662f0831e56393b2011b7cc9cd14e35..a80133d17368b05540179809d2bdab182248e729 100644 (file)
@@ -91,7 +91,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertTrue(unionExt2.exists());
         assertTrue(unionExt3.exists());
         assertTrue(unionExt4.exists());
-        assertFilesCount(parent, 30);
+        assertFilesCount(parent, 31);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
@@ -102,6 +102,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         Class<?> int32Ext1Class = Class.forName(pkg + ".Int32Ext1", true, loader);
         Class<?> int32Ext2Class = Class.forName(pkg + ".Int32Ext2", true, loader);
         Class<?> myDecimalTypeClass = Class.forName(pkg + ".MyDecimalType", true, loader);
+        Class<?> myDecimalType2Class = Class.forName(pkg + ".MyDecimalType2", true, loader);
         Class<?> stringExt1Class = Class.forName(pkg + ".StringExt1", true, loader);
         Class<?> stringExt2Class = Class.forName(pkg + ".StringExt2", true, loader);
         Class<?> stringExt3Class = Class.forName(pkg + ".StringExt3", true, loader);
@@ -264,6 +265,30 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         obj = expectedConstructor.newInstance(new BigDecimal("3.14"));
         assertEquals(obj, defInst.invoke(null, "3.14"));
 
+        // typedef my-decimal-type2
+        assertFalse(myDecimalType2Class.isInterface());
+        assertContainsField(myDecimalType2Class, VAL, BigDecimal.class);
+        assertContainsField(myDecimalType2Class, RANGE, List.class);
+        assertContainsFieldWithValue(myDecimalType2Class, "serialVersionUID", Long.TYPE, -672265764962082714L, BigDecimal.class);
+        assertEquals(3, myDecimalType2Class.getDeclaredFields().length);
+        assertContainsMethod(myDecimalType2Class, BigDecimal.class, "getValue");
+        expectedConstructor = assertContainsConstructor(myDecimalType2Class, BigDecimal.class);
+        assertContainsConstructor(myDecimalType2Class, myDecimalType2Class);
+        assertEquals(2, myDecimalType2Class.getDeclaredConstructors().length);
+        assertContainsMethod(myDecimalType2Class, BigDecimal.class, GET_VAL);
+        assertContainsDefaultMethods(myDecimalType2Class);
+        defInst = assertContainsMethod(myDecimalType2Class, myDecimalType2Class, "getDefaultInstance", String.class);
+        assertContainsGetLengthOrRange(myDecimalType2Class, false);
+        assertEquals(6, myDecimalType2Class.getDeclaredMethods().length);
+
+        List<Range<BigDecimal>> decimal2RangeConstraints = new ArrayList<>();
+        decimal2RangeConstraints.add(Range.closed(new BigDecimal("0"), new BigDecimal("1")));
+        arg = new BigDecimal("1.4");
+        expectedMsg = String.format("Invalid range: %s, expected: %s.", arg, decimal2RangeConstraints);
+        assertContainsRestrictionCheck(expectedConstructor, expectedMsg, arg);
+        obj = expectedConstructor.newInstance(new BigDecimal("0.14"));
+        assertEquals(obj, defInst.invoke(null, "0.14"));
+
         // typedef union-ext1
         assertFalse(unionExt1Class.isInterface());
         assertContainsField(unionExt1Class, "_int16", Short.class);
index 19d2eb1d5ee807111e24e2f392d02358f1b76340..911096606efee2258902f48d7947ec4b56677297 100644 (file)
@@ -95,6 +95,13 @@ module foo {
         }
     }
 
+    typedef my-decimal-type2 {
+        type decimal64 {
+            fraction-digits 18;
+            range "0..1";
+        }
+    }
+
     typedef union-ext1 {
         type union {
             type int16 {