The Script Editor in Servoy Developer offers full code completion (a.k.a. IntelliSense or autocomplete) and designtime code validation.
As JavaScript has no means to declare the type of a variable, the type of a function parameter or the return type of a function, it is not possible to get 100% correct results by just analyzing the JavaScript code itself.
In order to improve the quality of the code completion and code validation, functions and variables can be annotated with JSDoc to provide the missing information.
Besides the benefits for code completion and validation, adding JSDoc to JavaScript code also improves the readability of the code for other developers, as JSDoc allows for adding more info than just the typing info.
Using the JSDoc plugin hosted on ServoyForge it is also possible to generate HTML documentation of the JavaScript code in a Solution, based on the JSDOc supplied.
In This Chapter
What does JSDoc consist of?
The JSDoc syntax consists of a set of JSDoc tags, contained in JSDoc comments.
JSDoc comments are like multi-line JavaScript comments, but the opening tag is '/*' instead of just '/'
Some of the JSDoc tags require a Type Expression as one of the parameters and most allow for an extra description behind the tag and it's parameters.
Example
/** * A simple demo function that outputs some text * @author Tom * @private * * @param {String} text The text that will be written to the output * @throws (String) * returns Boolean * * @example try { * saySomething('Hello world!'); * } catch(e) { * * } * * @see application.output * @since 1.0 * @version 1.0.1<br> * - Added some more JSDoc tags for the demo */ function saySomething(text) { if (text == null || text.length == 0) { throw "Invalid input!" } application.output(text); return true; }
Where does JSDoc come from and which syntax is supported
JSDoc is not a official standard, but the defacto standard is is defined by the JSDoc Toolkit project. The other major definer of JSDoc is Google Closure Compiler's support for JavaScript annotation.
The JSDoc syntax supported by the Servoy Developer IDE is derived from the JSDoc Toolkit and Google Closure Compiler's support for JavaScript annotation, plus some custom Servoy extensions.
See #JSDoc Tags and #Type Expressions below for the supported tags and their syntax.
Working with JSDoc in the Script Editor
As mentioned in the intro, the Script Editor in Servoy Developer utilizes JSDoc to improve the quality of code completion and validation.
The Script Editor and Servoy Developer in general also facilitates the creation of JSDoc comments:
- When creating functions and variables through the wizards in the Solution Explorer or the Properties pane linked to the Form Editor, Servoy will automatically generate the variable or function with JSDoc comments.
- When manually creating variables and functions inside the Script Editor, using code completion it is possible to select Script Templates for new variables or functions that include the JSDoc comments
- When working with existing variables and functions, the SCript Editor has a function to automatically generate the JSDoc comments for the selected variable or function. This function can be accessed through:
- Alt-Shift-J
- Context Menu > Source > Generate Element Comments
- Inside the JSDoc comment, the Script Editor offers code completion for the available JSDoc tags if the "@" sign is entered and then code completion is requested (Control-Space)
When hovering over a reference to the variable of function somewhere in the Solution, the tooltip will show the JSDoc for the variable/function.
Note that the Script Editor will always generate a JSDoc comment block with a @properties tag when saving the Script editor, if no JSDoc comments have been defined. The @properties tag is a tag containing information for Servoy to provide proper linking and versioning.
JSDoc Tags
The following JSDoc tags are supported in the Script Editor. This means that the JSDoc tags will be rendered without the "@" sign when hovering over a reference tot he function or variable.
The developer can add any custom tag to the JSDoc comment, but besides being shown in the tooltip when hovering over references it will not do anything.
Tag |
Syntax & Examples |
Context |
Impact |
Description |
||
---|---|---|---|---|---|---|
@AllowToRunInFind |
@AllowToRunInFind |
function |
Determines if the function will be executes in FindMode when used as an event handler |
Custom Servoy JSDoc tag to annotate a function that it can be run if the Form on which the function is ran is in FindMode |
||
@author |
@author userName |
function, variable |
none |
Indicates the author of the code |
||
@constructor |
@constructor |
function |
This will show a different icon on the Script Outline view. besides that no further impact |
|
||
@deprecated |
@deprecated |
function, variable |
Accessing a deprecated variable or calling a deprecated function will produce a builder marker in Servoy Developer |
Indicates that the function or variable is obsolete or has been replaced and should be used anymore. |
||
@example |
@example |
function |
none |
Tag allowing to provide some sample code how to use the function or variable. Multiline content is possible my including "<br>" as line-breaks behind each line of content |
||
@param |
@param {Type} name parameterDescription |
function |
Builder markers will be generated in Servoy Developer if the function is called with values for the parameters that do no |
Describe function parameters. |
||
@private |
@private |
function, variable |
Accessing a private variable/function from outside the scope in which it is declared will generate a builder marker in Servoy Developer |
Annotates a variable or function as accessible only from within the file in which it is declared |
||
@protected |
@protected |
function, variable |
Accessing a protected variable/function from outside the scope in which it is declared or a child scope will generate a builder marker in Servoy Developer |
Annotates a variable or function as accessible from within the same file in which it is declared and all files that extend this file |
||
@return |
@return {Type} |
function |
The specified type is used by the build process to determine the correctness of the code that uses the returned value |
Annotates the type of the returned value. |
||
@returns |
@returns {Type} |
function |
see @return |
alias for @return |
||
@see |
@see seeDescription |
function, variable |
none |
Tag to provide pointers to other parts of the code that are related |
||
@since |
@since versionDescription |
function, variable |
none |
Tag to provide information about in which version of the code the variable or function was introduced |
||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ae06ffe0-a426-450d-a755-4f369946b5f1"><ac:plain-text-body><![CDATA[ |
@SuppressWarnings |
@SuppressWarnings ([deprecated], [hides], [wrongparameters], [undeclared]) |
function |
Stop the generation of builder markers in Servoy Developer for the specified warnings |
Custom Servoy JSDoc tag to suppress builder markers of a certain type within a function. |
]]></ac:plain-text-body></ac:structured-macro> |
@throws |
@throws {Type} |
function |
none |
Tag to describe the type of Exceptions that can be raised when the function is called. |
||
@type |
@type {Type} |
variable, inline variable, (function*) |
The specified type is used by the build process to determine the correctness of the code that uses the variable |
Tag to specify the type of the value that a variable can hold. |
||
@version |
@version versionDescription |
function, variable |
none |
Tag to provide information about the version of the code |
A file can be either a Form JavaScript file or the globals JavaScript file. Only Form can be extended, thus the @protected tag is not relevant for annotating variables and functions within the globals JavaScript file
Type Expressions
Type Expressions are used to describe the type and/or structure of data in the following cases:
Use case |
Tag |
Example |
---|---|---|
function parameters |
@param |
/** |
function return type |
@return |
/** |
functions exceptions |
@throws |
/** |
variables |
@type |
/** |
|
|
|
A Type Expression is to always be surrounded by curly braces: {typeExpression}. Note that when using the Object Type expression variation that start and stops with curly braces as well, this results in double opening and closing braces.
Expression name |
Syntax example |
Context |
Comments |
---|---|---|---|
Named type |
{String} |
@param, @return, @type, @throws |
The complete list of available types can be seen by triggering Code Completion inside the curly braces in the Script Editor |
AnyType |
* |
@param, @return, @type, @throws |
|
OR Type |
{String|Number} |
@param, @return, @type, @throws |
|
REST Type |
{...String} |
@param |
|
Array Type |
{String[]} |
@param, @return, @type, @throws |
|
Object Type |
{Object<String>} |
@param, @return, @type, @throws |
|
Object Type with optional properties |
{ {name:String, [age]:Number}} |
@param, @return, @type, @throws |
|
JSFoundset type |
{JSFoundset<db:/udm/contacts>}1 |
@param, @return, @type |
|
JSRecord type |
{JSRecord<db:/udm/contacts>}1 |
@param, @return, @type |
|
JSDataSet type |
{JSDataSet<{name:String, age:Number}>} |
@param, @return, @type |
|
RuntimeForm Type |
{RuntimeForm<superFormName>} |
@param, @return, @type |
|
1 the value in between <..> is the datasource notation that is built up of the database server and tablename: db:/{serverName}/{tableName}
Casting
When you have an array/object which holds some elements that you get by index (array[1]) or by name (array['name'] or object.name) and the array doesn't specify the type of the objects it holds like Array<String> or it does hold a super type so not the actual type an example is Servoy own form elements object/array.
The elements of the form is typed as an Object<RuntimeComponent> because all elements do have that type in common. RuntimeComponent has for example the background color and so on. But if you want to have a specific property called of a certain element in the element scope/object like: elements.mylabel.text, then this text property is not someting that the RuntimeComponent type has, but that is a property of the RuntimeLabel type. So to access that text property without any warning you have to cast it.
Casting only works when making a new variable where you specify through JSDoc the type and assign the element from the Array or Object to that variable. So instead of doing this:
elements.mylabel.text = "hallo"
You have to do this:
/** @type {RuntimeLabel} */ var mylabel = elements.mylabel; mylabel.text = "hallo"