lwjgl3 icon indicating copy to clipboard operation
lwjgl3 copied to clipboard

Separation of documentation from the main generator

Open ShadowLordAlpha opened this issue 9 years ago • 6 comments

As the title says separate the documentation of methods and fields from the generator. This would help when cleaning up or changing the documentation on different methods or fields as people who would like to contribute would have a much easier time than going though the generator template files (they look a bit more confusing then they are) and would allow for translation into other languages if people want that and put in the time to do so (or google translate with someone to grammar check it). To do this I thought of two different ways.

  1. Basically just give them all variable names that are loaded on execution similar to a properties file. This would probably be the simpler of the two methods to implement but is also the less flexible of the two as basically you just replace the current documentation with a variable that is loaded from a properties or other type of file.

  2. This requires a bit more work to the generator as instead of just simply making the current documentation a variable it would function as basically another template that, as the generator works, would look up the documentation on each part looking up the methods by name very similar to what it currently looks like. If there is nothing in the documentation template no comment of a very generic one could be generated.

It could look something like this

Class(
"AL10",
"""
Native bindings to AL 1.0 functionality.
"""
)

Field(
"NO_ERROR",
"""
Error conditions.
"""
)

Method(
"GetError",
"""
Enables AL capabilities.
""",
Param("target", "the capability to enable")

)

Method would probably also have other things like Return("documentation") and See mostly creating a one to one mapping to javadoc annotations making it relatively simple to understand.

Just as a note the point isn't really to make the generator simpler (the second one probably makes it much more complicated) but to make the template and documentation of generated code easier to use. For documentation you will not have to worry about messing with some part of the generator by accident and for the templates it moves out all the documentation for the generated methods making them easier to read without having to scroll though a lot of unneeded text that you mostly do not care about when working on one part or the other.

ShadowLordAlpha avatar Mar 27 '16 11:03 ShadowLordAlpha

This is a great idea.

Spasi avatar Mar 27 '16 11:03 Spasi

Ok so I was thinking more on what the format could look like and came up with this GLFW.dtpl

It should be easy to understand if you read it but basically it goes

doc:type:${name|group}:$identifier

where type is

  • package
  • class
  • field
  • method

the next part is group or name and it tells what the identifier after it is so if its name it will be the name of the method or if it is group (for field) then it will be a single comment for that whole group.

so it would look something like

doc:field:group:function_keys {
Function keys.
}

OR

doc:field:name:MOD_SHIFT {
If this bit is set one or more Shift keys were held down.
}

methods are a bit more tricky as they also have different annotations that can be used so after the main documentation they would have their annotations in the same fashion like so

doc:method:name:$identifier{}:$annotation:$arg

or

doc:method:name:$identifier{}:$annotation

where arg is optional and simply turned into a string and added as the first word after the annotation so the above would be turned into something like this

/**
 * @annotation arg
 *
 */
identifier() {

}

example

doc:method:name:GetVersion {
Retrieves the major, minor and revision numbers of the GLFW library. It is intended for when you are using GLFW as a shared library and want to ensure
that you are using the minimum required version.

Notes:
<ul>
<li>Any or all of the version arguments may be $NULL.</li>
<li>This function always succeeds.</li>
<li>This function may be called before #Init().</li>
<li>This function may be called from any thread</li>
</ul>
}:param:major {
where to store the major version number, or $NULL
}:param:minor {
where to store the minor version number, or $NULL
}:param:rev {
where to store the revision number, or $NULL
}.since {
version 1.0
}

would turn into something like

/**
 * Retrieves the major, minor and revision numbers of the GLFW library. It is intended for when you are using GLFW as a shared library and want to ensure
 * that you are using the minimum required version.
 * 
 * <p>Notes:</p>
 * 
 * <ul>
 * <li>Any or all of the version arguments may be {@code NULL}.</li>
 * <li>This function always succeeds.</li>
 * <li>This function may be called before {@link #glfwInit Init}.</li>
 * <li>This function may be called from any thread.</li>
 * </ul>
 *
 * @param major where to store the major version number, or {@code NULL}
 * @param minor where to store the minor version number, or {@code NULL}
 * @param rev   where to store the revision number, or {@code NULL}
 *
 * @since version 1.0
 */
public static void glfwGetVersion(ByteBuffer major, ByteBuffer minor, ByteBuffer rev) {
. . .
}

they could also just be fully formatted inside the main documentation part.

alternate methods should also have some way of documenting them though for now simply auto generated methods that point to the original documented version like it currently does should be fine.

ShadowLordAlpha avatar Mar 29 '16 06:03 ShadowLordAlpha

I'll be posting a JSON version later that would most likely be much better to use for the reasons being talked about in #173

ShadowLordAlpha avatar Mar 29 '16 21:03 ShadowLordAlpha

Wall of text

{
    "type": "documentation",
    "filename": "GLFW.java",
    "max_line_length": 100,
    "overall": "Copyright LWJGL. All rights reserved.\\nLicense terms: http://lwjgl.org/license.php\\nMACHINE GENERATED FILE, DO NOT EDIT",
    "package": "LISENCE.txt",
    "classes": [{
        "name": "GLFW",
        "doc": "Native bindings to the <a href="http://www.glfw.org/docs/latest/">GLFW</a> library.\\n\\nGLFW is a free, Open Source, multi-platform library for opening a window, creating an OpenGL context and managing input. It is easy to integrate into existing applications and does not lay claim to the main loop.",

        "variables": [{
            "name": "GLFW_VERSION_MAJOR",
            "group": null,
            "doc": "The major version number of the GLFW library. This is incremented when the API is changed in non-compatible ways."

        },
        {
            "name": null,
            "group": "function_keys",
            "doc": "Function keys."

        }],
        "methods": [{
            "name": "glfwGetMonitorPos",
            "alt": [{
                "arguments": ["long", "ByteBuffer", "ByteBuffer"],
                "doc": "Returns the position, in screen coordinates, of the upper-left corner of the specified monitor.\n\nAny or all of the position arguments may be {@code NULL}. If an error occurs, all non-{@code NULL} position arguments will be set to zero.\n\nThis function must only be called from the main thread.",
                "annotations": [{
                    "name": "param",
                    "arg": "monitor",
                    "doc": "the monitor to query",
                },
                {
                    "name": "param",
                    "arg": "xpos",
                    "doc": "where to store the monitor x-coordinate, or {@code NULL}",
                },
                {
                    "name": "param",
                    "arg": "ypos",
                    "doc": "where to store the monitor y-coordinate, or {@code NULL}",
                },
                {
                    "name": "since",
                    "arg": null,
                    "doc": "version 3.0",
                }] 
            },
            {
                "arguments": ["long", "IntBuffer", "IntBuffer"],
                "doc": "Alternative version of: {@link #glfwGetMonitorPos GetMonitorPos}",
                "annotations": [{
                    "name": "param",
                    "arg": "monitor",
                    "doc": "the monitor to query",
                },
                {
                    "name": "param",
                    "arg": "xpos",
                    "doc": "where to store the monitor x-coordinate, or {@code NULL}",
                },
                {
                    "name": "param",
                    "arg": "ypos",
                    "doc": "where to store the monitor y-coordinate, or {@code NULL}",
                },
                {
                    "name": "since",
                    "arg": null,
                    "doc": "version 3.0",
                }] 
            }]
        }]
    }]
}

so then lets go over the new wall of text i have.

starting off this file is

"type": "documentation",

this tells the reader that this Json object contains the documentation. The next line

"filename": "GLFW.java",

tells the reader what file this Json objects documentation is for. Then comes

"overall": "Copyright LWJGL. All rights reserved.\\nLicense terms: http://lwjgl.org/license.php\\nMACHINE GENERATED FILE, DO NOT EDIT",
"package": "LISENCE.txt",

This allows us to document the very top of the page and the package of the file separately. both of these could be files or contain what is printed.

now for the more complex parts. As java allows for nested classes we need the ability to have multiple class objects. inside each class object is its name so we can line up the documentation and the documentation that goes over the class deceleration. each class has a list of variables and methods that are documented in a similar way to above.

If I missed anything that would be needed please tell me.

ShadowLordAlpha avatar Mar 30 '16 18:03 ShadowLordAlpha

It's a good start. Comments:

  • The above example is trying to document the generated code (license header, Java types, alternative methods). We should be documenting the source templates instead (native types, one structure per method, etc).
  • It's better if there's a single file per template (i.e. per generated class), even if it is a bit wasteful for short classes. Classes with no content could be handled specially though (e.g. see ExtensionFlags.kt)

Spasi avatar Mar 31 '16 10:03 Spasi

The above example is trying to document the generated code (license header, Java types, alternative methods). We should be documenting the source templates instead (native types, one structure per method, etc).

The name methods are strings so they can be whatever is needed. They follow what the java files are currently because that's what I had when I came up with it. Because it will be documenting java code I thought it would be better if the documentation templates looked more like the java code they were documenting. For the variables part to change it to mimic the templates would be change the name field like this.

{
      "name": "VERSION_MAJOR",
      "group": null,
      "doc": "The major version number of the GLFW library. This is incremented when the API is changed in non-compatible ways."
}

Though I have no idea what your thinking for the acutal template files. For methods just change it so that there is no alt array and the names are different though I think it would be a good idea to be able to document the alternate methods differently but it is up to you what is done.

It's better if there's a single file per template (i.e. per generated class), even if it is a bit wasteful for short classes. Classes with no content could be handled specially though (e.g. see ExtensionFlags.kt)

I don't see anything keeping this from happening (maybe just change the array to a single object) though my idea was to have the template point to its documentation file so that all the generator has to look for is the templates and those tell it where the proper documentation template is.

ShadowLordAlpha avatar Mar 31 '16 16:03 ShadowLordAlpha