UNPKG

short-jsdoc

Version:

short and simple jsdoc Object Oriented syntax format and implementation

347 lines (199 loc) 12.2 kB
<!-- jsdoc getting started slides. Just open this file with your browser, you don't need to serve it. --> <!DOCTYPE html> <html> <head> <title>Title</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <style type="text/css"> @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic); body { font-family: 'Droid Serif'; } h1, h2, h3 { font-family: 'Yanone Kaffeesatz'; font-weight: normal; } .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; } body .remark-slide-content{font-size: 18px} body h2 {margin: 10px 0px 10px 0px;} </style> </head> <body> <textarea id="source"> class: center, middle # Getting started with short-jsdoc --- # Introduction So you want to document your sources with short-jsodc... Then you will be declaring modules that contain classes that contain methods and properties using annotations. This is called an *abstract syntax tree* or *AST*. --- #Example Let's start with an example of JavaScript code that contains a jsdoc comment. It declares a class *FileView* of module *myapp* that extends class *AbstractView* and contains a property *file* of type *FileData* and a method *deleteFileHandler* that accept a Function parameter and returns a *Promise* object: // @module myapp // @class FileView This view shows a single file @extends AbstractView // @property {FileData} file // @method deleteFileHandler Handles the delete file action // @param {Function} fn @returns {Promise} --- #Annotation syntax The tool will be consuming expressions like the following to build the AST. We call these expressions *annotations*: // @param {Color} color a description for the color parameter ##Annotation parts * ```@param``` is the annotation and defines the type of node we are declaring. In this case we are declaring a method parameter * ```{Color}``` is optional. Is a refence of the type of the node we are declaring. * ```color``` is optional too and it is the name of the node we are declaring. * The text ```a description for the color parameter``` is associated to the node and documents it --- #Tree structure * @module contain @class * @class contain @method @property @event * @method contain @param In short-jsdoc only certain nodes can contain children. We call these *parent nodes* and are: @module @method @property @event @class All other annotations are *leaf nodes* meaning they can't contain children and always belong to a parent node. Example of leaf nodes: @param @throws @returns @extends @static --- #Parser tool The parser will read your files from top to bottom parsing any annotation found in your source code comments. When a leaf node annotation is found, it is assigned as children of the last parsed parent node. When a parent node annotation is found it is assigned as children of the last parent node that matches the structure 'modules that contain classes that contains methods, etc'. Any kind of comment style can be used. Any @annotation name can be used so you can define your own semantics - they will be parsed as children of the last parent node read. Source code files must be auto-contenible - in other words you cannot make any assumptions about the order of the files being parsed. --- #Types Some nodes like parameters or returns can declare a type, which is a reference to class nodes. short-jsdoc heavily support types and can be of the following kinds ##Simple types Are just a reference to a class by name, for example: // @method getModel @returns {Banana} --- #Types ## Native types If you reference a JavaScript native type like String, Array, Object, etc., they will be binded to the [Mozilla JavaScript Types Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects). Some native types are Object, Number, Boolean, String, Array, Function, Error, etc Also you can choose to compile using the provided jsdoc for native types - copied and pasted from mozilla docs. In that case instead an external link you can navigate to the type as with any other types and the inherited information will be available. --- #Types ##Generic types These are inspirated in Java or C# generics. For example we can say that a parameter is an *Array* but we can also say it is an *Array of Bananas* : // @method addFruit @param {Array&lt;Banana>} fruits Generic types support arbitrary anidation: @method groupWires @returns {Object&lt;String,Array&lt;Wire>>} a map of wires by name. --- #Types ##Multiple types - (OR) Imagine a method in which its first param can be both a String or an Array. Then we can say so in jsdocs like this: @method foo @param {String|Array} p --- #Types ##Literal Object Because in JavaScript is very common to define Objects on the fly shortjsdoc supports an object literal type definition: @method foo @returns {id:String,colors:Array&lt;Color>,execute:Function} That means that the mehod *foo* returns an object with the properties *id* of type String, *color* of type Array of Color and *execute* of type Function. --- #Types There is jsdoc for libraries types like jQuery, Backbone, Underscore that you can also link in your applications. For example jQuery.Deferred, Backbone.View, etc. --- #Ignored comments Comments starting with the character '?' will be ignored, even if they contain annotations: //? @class Something will be ignored b the parser /*? @method foo also will be ignored */ --- #Talking about different classes on the same file In javascript it is common to be defining a class Foo, then in the middle of the file, define another class Bar and start talking about it, and then come back talking about the first class Foo, all on the same file. The recommended way to solve this problem with short jsdoc is making sure we are *standing* at the correct class. We use @class annotations as we use the 'cd' console command to set the current working directory to talk about relative files in there: // @class Foo this is the main class // @method {FooConfig} doTheWork Foo method that returns a new type that wi will describe now! // @class FooConfig bla, this class is declared at the middle of the file and we want to document it here! // @property width a property of FooConfig class - we close class FooConfig here and come back talking about class Foo // @class Foo // @property name a Foo class property --- #Talking about the same class in different files In JavaScript is very common that a class or module definition is made across several files. shortjsdoc support this by just telling the framework of what are we goint to talk about following the top to bottom file parsing: // file1.js // @module foo Some comment about module foo // @class Bar some comment about class Bar @property p1 // file2.js // @module foo More text for module foo // @class Bar More contant about class Bar @property @p2 That will result in a module *foo* containing both texts and containing a class Bar that will also contain both texts. --- #Text Markings Marks inside a node text can be defined using the syntax @?something. This is mostly used for defining references to other nodes or to external links from within the text. It is similar to java's @see annotation. We can use @?class AClass or @?method module.Class.method1 or @?property, @?event, etc. These markings will create a link to the referenced node in the output. Example: // @module client // @class CustomerModel This model represent a single customer. // The attributes of this model are defined by the @?class server.CustomerService service // @extends Backbone.Model Also, there is a @?ref that will accept any kind of node - but less efficient by the viewer tools. --- #Type alias There is a very powerful annotation @alias that let declare alias for types and even for annotations. Suppose you want to integrate an external jsdoc file in which the type 'float' is used instead of Number. You want the tool to replace each 'float' type with 'Number', so you would add the following (before): @alias class float Number Even more interesting, you want to create shortcuts to common js types, so instead writing Object *&lt; String, &lt; Array &lt; Number>>>* you can just write *O &lt; S, &lt; A &lt; N>>>*, well that can be done by just defining class alias: @alias class O Object @alias class A Array @alias class S String @alias class N NUmber Then when the type 'A' is found it will be replaced by 'Array' --- #Annotation alias the @alias plugin also supportsanother kind of aliasing that gives the user the power of creating aliases of annotations. For example, suppose that we are not documenting js-doc but another thing, like the grunt/gulp build tasks and we want to use the annotation @gulp-task to be proccessed as if they were @module, then we can just write: @alias annotation gulp-task module After that declaration, all annotations @gulp-task will be treated as if they were @module. --- Metadata Out ouf the hook metadata is supported via the annotations @metadata and @metadata-global. @metadata is used for adding some metadata property in the current primary annotation and @metadata-global is used for adding a metadata property in the global ast object. Example: Metadata in general is used by viewers like the html application to name or describe concepts We want the viewers to name classes as 'sections' and modules as 'books' so: @metadata-global class.name Section @metadata-global module.name Book we want the paricular class Apple to be named as a 'Chapter' @class Apple foo bar @extend Fruit @metadata class.name Chapter --- #Parsing stages. There are two main stages in short-jsdoc: parsing and type binding. ##Parsing This is the most important part, it will read your sources and make a basic AST. Nodes will be organized accordingly to a specific language, for example, in jsdoc modules will contain classes that will contain methods, etc. But in general the parsing tool is language agnostic and can be reused to process any language, not only jsdoc. var maker = new JsDocMaker(); var source = '//@module fruits @class Apple the science fruit @method inpirate @param {Person} p'; maker.addFile(source, 'apple.js'); var ast = maker.jsdoc(); The resulting *ast* variable contains a module fruits that contains a Apple class that contains a method *inspirate* that accept a parameter of type Person. We can access this type with the following code, but because it is not binded yet we can only access the referenced type name: ast.classes ['fruits.Apple'].methods.inspirate.param [0]. type === 'Person' --- #Parsing stages. ##Type Binding After we have a parsed AST we can then run a second utility over it called binding. It will bind all types found with the actual class node in the AST. This means, for each node that contains a type, it will look for the referenced class node and associate it For example, after parsing only we have the referenced class names only, but after binding it we will have easy access to the real referenced node. Parsing only is good for serializing the AST to JSON - you cannot serialize a binded AST. Based on our previous example, if we bind the AST we will can navigate through types: maker.postProccess(); maker.postProccessBinding(); ast.classes ['fruits.Apple'].methods.inspirate.param [0].type === ast.classes ['people.Person'] --- #The html application After the parser has extracted all the jsdoc AST information from given sources, there is a html single page application that renders all of this information in a navigable way with utilities like: * node text search * class hierarchy * known subclases * search type references * full AST tree </textarea> <script src="https://gnab.github.io/remark/downloads/remark-latest.min.js"> </script> <script> var slideshow = remark.create(); </script> </body> </html>