[mapguide-commits] r7225 - in sandbox/jng/swig-java: BuildTools/WebTools/IMake BuildTools/WebTools/IMake/Win32 Web/src/JavaApiEx

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Nov 26 00:18:15 PST 2012


Author: jng
Date: 2012-11-26 00:18:14 -0800 (Mon, 26 Nov 2012)
New Revision: 7225

Modified:
   sandbox/jng/swig-java/BuildTools/WebTools/IMake/IMake.cpp
   sandbox/jng/swig-java/BuildTools/WebTools/IMake/Win32/IMake.exe
   sandbox/jng/swig-java/BuildTools/WebTools/IMake/stdafx.h
   sandbox/jng/swig-java/Web/src/JavaApiEx/javaextensions.i
Log:
#9, #2114: Add IMake support for transplanting class API documentation and javadoc linkification of MapGuide class names

Modified: sandbox/jng/swig-java/BuildTools/WebTools/IMake/IMake.cpp
===================================================================
--- sandbox/jng/swig-java/BuildTools/WebTools/IMake/IMake.cpp	2012-11-26 06:38:45 UTC (rev 7224)
+++ sandbox/jng/swig-java/BuildTools/WebTools/IMake/IMake.cpp	2012-11-26 08:18:14 UTC (rev 7225)
@@ -23,6 +23,7 @@
 static string typedefs;
 static string nameSpace;
 static string package;
+static set<string> classesWithDocs;
 static map<string, string> typeReplacements;
 static map<string, bool> classes;
 static vector<string> headers;
@@ -530,6 +531,65 @@
     return itMethod != rootObjectMethods.end();
 }
 
+bool isAllSlashes(const string& str)
+{
+    for (int i = 0; i < str.length(); i++) {
+        if (str[i] != '/')
+            return false;
+    }
+    return str.length() > 3; //A "///" does not count
+}
+
+string linkifyJavaDocFragment(const string& str)
+{
+    std::vector<std::string> elems;
+    std::stringstream ss(str);
+    std::string item;
+    while(std::getline(ss, item, ' ')) {
+        elems.push_back(item);
+    }
+    std::string output;
+    for (int i = 0; i < elems.size(); i++) {
+        if (i != 0) {
+            output.append(" ");
+        }
+        //If it contains "Mg", assume it's a MapGuide class name and link-ify it
+        //TODO: Resolve :: to member links. Right now it just linkifies the Mg class name
+        int idx = elems[i].find("Mg");
+        if (idx != std::string::npos) {
+            std::string prefix;
+            std::string mgClassName;
+            std::string suffix;
+            //Collect characters before Mg
+            if (idx > 0) {
+                prefix = elems[i].substr(0, idx);
+            }
+            int cont = -1;
+            //Collect the characters in the MapGuide class name
+            for (int j = idx; j < elems[i].length(); j++) {
+                if (!isalnum(elems[i][j])) {
+                    cont = j;
+                    break;
+                } else {
+                    mgClassName += elems[i][j];
+                }
+            }
+            //Collect any characters afterwards
+            for (int j = cont; j < elems[i].length(); j++) {
+                suffix += elems[i][j];
+            }
+            output.append(prefix);
+            output.append("{@link ");
+            output.append(mgClassName);
+            output.append("}");
+            output.append(suffix);
+        } else {
+            output.append(elems[i]);
+        }
+    }
+    return output;
+}
+
 string doxygenToJavaDoc(const string& commentStr)
 {
     // Doxygen documentation translation overview:
@@ -658,18 +718,18 @@
     if (descriptionParts.size() > 0) {
         for (int i = 0; i < descriptionParts.size(); i++) {
             javaDoc.append(" *");
-            javaDoc.append(descriptionParts[i]);    
+            javaDoc.append(linkifyJavaDocFragment(descriptionParts[i]));    
             javaDoc.append("\n");
         }
         javaDoc.append(" *\n");
     } else {
-        javaDoc.append(" * TODO: Missing API Documentation here\n");
+        javaDoc.append(" * TODO: Missing API Documentation here (message inserted by IMake.exe)\n");
     }
 
     if (paramParts.size() > 0) {
         for (int i = 0; i < paramParts.size(); i++) {
             javaDoc.append(" * @param ");
-            javaDoc.append(paramParts[i]);
+            javaDoc.append(linkifyJavaDocFragment(paramParts[i]));
             javaDoc.append("\n");
         }
     }
@@ -677,7 +737,7 @@
     if (returnParts.size() > 0) {
         javaDoc.append(" * @return ");
         for (int i = 0; i < returnParts.size(); i++) {
-            javaDoc.append(returnParts[i]);
+            javaDoc.append(linkifyJavaDocFragment(returnParts[i]));
             if (i < returnParts.size() - 1)
                 javaDoc.append("\n * ");
         }
@@ -696,6 +756,22 @@
     return commentStr;
 }
 
+void outputClassDoc(const string& className, const string& commentStr)
+{
+    //Nothing for PHP
+    if (language == php)
+        return;
+
+    string convertedDoc;
+    if (language == java) {
+        convertedDoc = doxygenToJavaDoc(commentStr);
+        fprintf(docOutFile, "\n%%typemap(javaclassmodifiers) %s %%{%s public%%}\n", className.c_str(), convertedDoc.c_str());
+    } else if(language == csharp) {
+        convertedDoc = doxygenToCsharpDoc(commentStr);
+        fprintf(docOutFile, "\n%%typemap(csclassmodifiers) %s %%{%s public%%}\n", className.c_str(), convertedDoc.c_str());
+    }
+}
+
 void outputMethodDoc(const string& className, const string& methodDecl, const string& commentStr)
 {
     //Nothing for PHP
@@ -774,6 +850,39 @@
 
     string commentStr;
     string methodDecl;
+
+    //NOTE: This can get called multiple times for a given class with various offsets, so use a std::set to guard
+    //against duplicate class documentation entries
+    if (!translateMode && classesWithDocs.find(className) == classesWithDocs.end() && begin > 0) {
+        
+        int slashesCount = 0;
+        for (int i = 0; i < begin; i++) {
+            string token = tokens[i];
+            if(token == "")
+                continue;
+            //pickup the doc comments for the class, if any.
+            //all contiguous doc comment will be considered part of the class comment
+            if(strncmp(token.c_str(), "///", 3) == 0)
+            {
+                if (isAllSlashes(token))
+                {
+                    slashesCount++;
+                }
+
+                if (slashesCount > 1) //Stop here, as this is generally the start of the documentation for the first method in the class
+                    break;
+
+                commentStr.append(token);
+                commentStr.append("\n");
+                continue;
+            }
+        }
+        if (!commentStr.empty()) {
+            outputClassDoc(className, commentStr);
+            commentStr.clear();
+            classesWithDocs.insert(className);
+        }
+    }
     for(int i = begin; i <= end; i++)
     {
         assignmentAdded = false;

Modified: sandbox/jng/swig-java/BuildTools/WebTools/IMake/Win32/IMake.exe
===================================================================
(Binary files differ)

Modified: sandbox/jng/swig-java/BuildTools/WebTools/IMake/stdafx.h
===================================================================
--- sandbox/jng/swig-java/BuildTools/WebTools/IMake/stdafx.h	2012-11-26 06:38:45 UTC (rev 7224)
+++ sandbox/jng/swig-java/BuildTools/WebTools/IMake/stdafx.h	2012-11-26 08:18:14 UTC (rev 7225)
@@ -12,6 +12,7 @@
 #include <algorithm>
 #include <deque>
 #include <map>
+#include <set>
 #include <iostream>
 #include <sstream>
 #include <time.h>

Modified: sandbox/jng/swig-java/Web/src/JavaApiEx/javaextensions.i
===================================================================
--- sandbox/jng/swig-java/Web/src/JavaApiEx/javaextensions.i	2012-11-26 06:38:45 UTC (rev 7224)
+++ sandbox/jng/swig-java/Web/src/JavaApiEx/javaextensions.i	2012-11-26 08:18:14 UTC (rev 7225)
@@ -68,39 +68,61 @@
 %typemap(javainterfaces) collection_type "Collection<item_type>"
 //This is the java.util.Collection implementation that is injected into each java proxy class
 %typemap(javacode) collection_type %{
-
+    /**
+     * An iterator to iterate over this collection
+     */
     class ItemIterator implements Iterator<item_type> {
         private collection_type _collection;
         private int _pos;
+        private int _count;
         
         public ItemIterator(collection_type c) { 
             _collection = c; 
+            _count = _collection.getCount();
             _pos = -1;
         }
         
+        /**
+         * Returns true if the iteration has more elements
+         */
         public boolean hasNext() {
-            return _pos + 1 <= _collection.getCount();
+            return _pos + 1 <= _count;
         }
         
+        /**
+         * Returns the next item_type in the collection
+         */
         public item_type next() {
             _pos++;
-            if (_pos >= _collection.getCount())
+            if (_pos >= _count)
                 throw new NoSuchElementException();
             return _collection.getItem(_pos);
         }
         
+        /**
+         * Removes from the underlying collection the last element returned by the iterator (not supported).
+         */
         public void remove() {
             throw new UnsupportedOperationException();
         }
     }
     
+    /**
+     * Returns an iterator over the elements in this collection.
+     */
     public Iterator<item_type> iterator() { return new ItemIterator(this); }
 
+    /**
+     * Ensures that this collection contains the specified element (optional operation).
+     */
     public boolean add(item_type item) {
         this.addItem(item);
         return true;
     }
 
+    /**
+     * Adds all of the elements in the specified collection to this collection (optional operation).
+     */
     public boolean addAll(Collection<? extends item_type> c) {
         int added = 0;
         for (item_type item : c) {
@@ -110,6 +132,9 @@
         return added > 0;
     }
 
+    /**
+     *  Returns true if this collection contains the specified element.
+     */
     public boolean contains(Object o) {
         if (o instanceof item_type) {
             return this.contains((item_type)o);
@@ -117,6 +142,9 @@
         return false;
     }
 
+    /**
+     * Returns true if this collection contains all of the elements in the specified collection.
+     */
     public boolean containsAll(Collection<?> c) {
         for (Object o : c) {
             if (!this.contains(o))
@@ -125,8 +153,14 @@
         return true;
     }
 
+    /**
+     * Returns true if this collection contains no elements.
+     */
     public boolean isEmpty() { return this.getCount() == 0; }
 
+    /**
+     * Removes a single instance of the specified element from this collection, if it is present (optional operation).
+     */
     public boolean remove(Object o) {
         if (o instanceof item_type) {
             return this.remove((item_type)o);
@@ -134,6 +168,9 @@
         return false;
     }
 
+    /**
+     * Removes all of this collection's elements that are also contained in the specified collection (optional operation).
+     */
     public boolean removeAll(Collection<?> c) {
         int removed = 0;
         for (Object o : c) {
@@ -143,6 +180,9 @@
         return removed > 0;
     }
 
+    /**
+     * Retains only the elements in this collection that are contained in the specified collection (optional operation).
+     */
     public boolean retainAll(Collection<?> c) {
         int removed = 0;
         ArrayList<item_type> remove = new ArrayList<item_type>();
@@ -158,8 +198,14 @@
         }
     }
 
+    /**
+     * Returns the number of elements in this collection.
+     */
     public int size() { return this.getCount(); }
 
+    /**
+     * Returns an array containing all of the elements in this collection.
+     */
     public Object[] toArray() {
         int count = this.getCount();
         Object[] items = new Object[count];
@@ -169,6 +215,9 @@
         return items;
     }
 
+    /**
+     * Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array.
+     */
     public <item_type> item_type[] toArray(item_type[] a) {
         Object[] items = this.toArray();
         if (a.length >= items.length) {
@@ -199,32 +248,48 @@
 %typemap(javainterfaces) collection_type "java.lang.Iterable<item_type>"
 //This is the java.lang.Iterable<T> implementation that is injected into each java proxy class
 %typemap(javacode) collection_type %{
-
+    /**
+     * An iterator to iterate over this collection
+     */
     class ItemIterator implements Iterator<item_type> {
         private collection_type _collection;
         private int _pos;
+        private int _count;
         
         public ItemIterator(collection_type c) { 
             _collection = c; 
+            _count = _collection.getCount();
             _pos = -1;
         }
         
+        /**
+         * Returns true if the iteration has more elements
+         */
         public boolean hasNext() {
-            return _pos + 1 <= _collection.getCount();
+            return _pos + 1 <= _count;
         }
         
+        /**
+         * Returns the next item_type in the collection
+         */
         public item_type next() {
             _pos++;
-            if (_pos >= _collection.getCount())
+            if (_pos >= _count)
                 throw new NoSuchElementException();
             return _collection.getItem(_pos);
         }
         
+        /**
+         * Removes from the underlying collection the last element returned by the iterator (not supported).
+         */
         public void remove() {
             throw new UnsupportedOperationException();
         }
     }
-    
+
+    /**
+     * Returns an iterator over the elements in this collection.
+     */
     public Iterator<item_type> iterator() { return new ItemIterator(this); }
     
 %}



More information about the mapguide-commits mailing list