Bug 5151 Java binding missing @return 26/41426/6
authorRyan Goulding <ryandgoulding@gmail.com>
Wed, 6 Jul 2016 19:26:19 +0000 (15:26 -0400)
committerTom Pantelis <tpanteli@brocade.com>
Tue, 12 Jul 2016 12:29:07 +0000 (12:29 +0000)
Adds @return functionality to interface accessors.  The idea is to generate a
meaningful return label so that we don't get warnings during compilation for
missing return statements.  A test is added to verify that the return statement
is formatted appropriately.

Change-Id: I01875b788622cab002653a03ea2d844d2c954b77
Signed-off-by: Ryan Goulding <ryandgoulding@gmail.com>
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/InterfaceTemplate.xtend
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/Bug5151Test.java [new file with mode: 0644]
binding/mdsal-binding-java-api-generator/src/test/resources/compilation/bug5151/bug5151.yang [new file with mode: 0644]

index 43cfaae1c4424259ec924635aed5abb232ba7762..409b1266c2c3b946b1bb9a8bd70456e775e06423 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
 import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
 import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.TypeMember
 import org.opendaylight.yangtools.yang.common.QName
 
 abstract class BaseTemplate {
@@ -96,6 +97,10 @@ abstract class BaseTemplate {
         return getter.name.substring(prefix).toFirstLower;
     }
 
+    final protected def isAccessor(MethodSignature maybeGetter) {
+        return maybeGetter.name.startsWith("is") || maybeGetter.name.startsWith("get");
+    }
+
     /**
      * Template method which generates the getter method for <code>field</code>
      *
@@ -242,6 +247,25 @@ abstract class BaseTemplate {
         '''.toString
     }
 
+    def protected String formatDataForJavaDoc(TypeMember type, String additionalComment) {
+        val StringBuilder typeDescriptionBuilder = new StringBuilder();
+        if (!type.comment.nullOrEmpty) {
+            typeDescriptionBuilder.append(formatToParagraph(type.comment))
+            typeDescriptionBuilder.append(NEW_LINE)
+            typeDescriptionBuilder.append(NEW_LINE)
+            typeDescriptionBuilder.append(NEW_LINE)
+        }
+        typeDescriptionBuilder.append(additionalComment)
+        var typeDescription = wrapToDocumentation(typeDescriptionBuilder.toString)
+        return '''
+            «typeDescription»
+        '''.toString
+    }
+
+    def asCode(String text) {
+        return "<code>" + text + "</code>"
+    }
+
     def asLink(String text) {
         val StringBuilder sb = new StringBuilder()
         var tempText = text
index e8ce4c0e2e2e7c2b83990ddd68a06ac61e741aaa..61c7b2a4cfc7bd2d8186a6f8dbeb15e34ace4b85 100644 (file)
@@ -175,7 +175,12 @@ class InterfaceTemplate extends BaseTemplate {
     def private generateMethods() '''
         «IF !methods.empty»
             «FOR m : methods SEPARATOR "\n"»
-                «m.comment.asJavadoc»
+                «IF !m.isAccessor»
+                    «m.comment.asJavadoc»
+                «ELSE»
+                    «formatDataForJavaDoc(m, "@return " + asCode(m.returnType.fullyQualifiedName) + " "
+                    + asCode(propertyNameFromGetter(m)) + ", or " + asCode("null") + " if not present")»
+                «ENDIF»
                 «m.annotations.generateAnnotations»
                 «m.returnType.importedName» «m.name»(«m.parameters.generateParameters»);
             «ENDFOR»
diff --git a/binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/Bug5151Test.java b/binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/Bug5151Test.java
new file mode 100644 (file)
index 0000000..526c7c9
--- /dev/null
@@ -0,0 +1,88 @@
+package org.opendaylight.yangtools.sal.java.api.generator.test;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import org.junit.Test;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.sal.java.api.generator.GeneratorJavaFile;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Bug5151 involves adding <code>{@literal @}return</code> annotations to accessor methods.
+ */
+public class Bug5151Test extends BaseCompilationTest {
+
+    private static final String BUG_ID = "bug5151";
+
+    @Test
+    public void test() throws Exception {
+        final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + BUG_ID);
+        assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
+        final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + BUG_ID);
+        assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
+
+        generateTestSources(CompilationTestUtils.FS + "compilation" + CompilationTestUtils.FS + BUG_ID, sourcesOutputDir);
+
+        // Test if sources are compilable
+        CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
+
+        final Map<String, File> generatedFiles = getFiles(sourcesOutputDir);
+        assertEquals(3, generatedFiles.size());
+
+        final File fooContainerFile = generatedFiles.get("FooContainer.java");
+        assertNotNull(fooContainerFile);
+        assertTrue(findInFile(fooContainerFile,
+                "@return <code>java.lang.String</code> <code>fooInContainer</code>, "
+                        + "or <code>null</code> if not present"));
+
+        final File fooDataFile = generatedFiles.get("FooData.java");
+        assertNotNull(fooDataFile);
+        assertTrue(findInFile(fooDataFile, "FooContainer</code> <code>fooContainer</code>, or <code>null</code> if not present"));
+
+        CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
+    }
+
+    private static boolean findInFile(final File file, final String searchText) throws FileNotFoundException {
+        final Scanner scanner = new Scanner(file);
+        while (scanner.hasNextLine()) {
+            final String nextLine = scanner.nextLine();
+            if (nextLine.contains(searchText)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir) throws Exception {
+        final List<File> sourceFiles = CompilationTestUtils.getSourceFiles(resourceDirPath);
+        final SchemaContext context = TestUtils.parseYangSources(sourceFiles);
+        final List<Type> types = bindingGenerator.generateTypes(context);
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
+        generator.generateToFile(sourcesOutputDir);
+    }
+
+    private static Map<String, File> getFiles(final File path) {
+        return getFiles(path, Maps.newHashMap());
+    }
+
+    private static Map<String, File> getFiles(final File path, final Map<String, File> files) {
+        final File [] dirFiles = path.listFiles();
+        for (File file : dirFiles) {
+            if (file.isDirectory()) {
+                return getFiles(file, files);
+            } else {
+                files.put(file.getName(), file);
+            }
+        }
+        return files;
+    }
+}
diff --git a/binding/mdsal-binding-java-api-generator/src/test/resources/compilation/bug5151/bug5151.yang b/binding/mdsal-binding-java-api-generator/src/test/resources/compilation/bug5151/bug5151.yang
new file mode 100644 (file)
index 0000000..fffff78
--- /dev/null
@@ -0,0 +1,18 @@
+module foo {
+    namespace "urn:test:foo";
+    prefix foo;
+
+    revision 2016-07-06 {
+    }
+
+    leaf class {
+        type string;
+    }
+
+    container foo-container {
+        leaf foo-in-container {
+            type string;
+            description "foo-in-container description";
+        }
+    }
+}
\ No newline at end of file