Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
VJET/Overview of VJETDoc
VJETJavaScript supports a declarative form of comment syntax called VJETDoc, which leverages regular JavaScript comments to provide type information about JavaScript constructs.
This document describes VJETDoc syntax. Some background with OO terminology is helpful, but not required to understand the structure of VJETDoc
Contents
- 1 Type Declarations and VJETDoc
- 2 VJET's Primary Goals
- 3 Learning VJETDoc
- 4 Native JavaScript language comments
- 5 What does a VJETDoc comment structure look like?
- 6 Top-level VJETDoc Comment Structure
- 7 Mixing VJETDoc and JavaScript code comment
- 8 Using VJETDoc with native JavaScript types
- 9 What constructs can we type?
- 10 What types can I use in the VJETDoc?
- 11 Type Names
- 12 Type Reference
- 13 Where can we apply VJETDoc typing?
Type Declarations and VJETDoc
With VJETDoc, you can type all JavaScript constructs:
- globals
- classes
- properties
- functions
- variables
- statements
- expressions
- object literals
- and more.
VJETDoc is based on Java's definition syntax. VJETDoc has been extended to support qualifying type information such as the notion of final, abstract and access control. In cases of JavaScript constructs that don't exist in Java, we turned to typing constructs from other mature languages, such as C++s' scoping operator.
There were many advantages to using type syntaxes from existing languages:
- Familiar to many developers
- Don't try to invent an entirely new declaration syntax for a rich typing system
- Leverage almost the same type syntax in Java and JavaScript
- Future support for Java2Js and Js2Java this makes translation easier and more 1:1
- Definition is compact and easier to read and understand than something like JsDoc style declarations
- Declaration comments can appear either before, after, or interspersed with JavaScript declarations
- It's possible for type declarations to coexist on the same line with JavaScript
VJET's Primary Goals
- Type all aspects of JavaScript
- Introduce more structured and abstract typing capabilities such as those found in C++ and Java
The benefits of providing complete type support for JavaScript is covered in another document, but a short list includes consistency, usability, documentation, tool support (IDE, debugger, Modeling, Document Generators, Refactoring) and more.
Learning VJETDoc
The best way to learn VJETDoc is through the VJET JS IDE. The IDE enforces the type information you apply to JavaScript constructs and provides code completions and proposals based on the VJETDoc type information. Not only is the IDE a productivity tool, but it's also a great learning tool.
VJETJS has typed all global types, objects, and functions available in native JavaScript. Experiment using code assistance with native JavaScript to see how the type information is used by the IDE; you'll want to begin adding VJETDoc to your own JavaScript. Since VJETDoc is based on JsDoc, you can also add documentation comments which will display using the Eclipse hover help, F2, etc.
VJET IDE also supports classic click-n-run and debug for VJET JS code. This is included with the familiar Eclipse launchers. VJET also supports a main(...) entry point convention function that follows the Java model so it's easy to identify where and what code you would like to run. The ability to execute and debug in a single environment will help you to learn VJET JS quickly.
VJET JS also has provided complete typing for a number of 3rd party JavaScript libraries. These libraries are also a great way to see how VJETDoc is used to describe JavaScript code you are already familiar with. See the [VJET Download page] for more info.
Conventions
As we describe the VJETDoc, we use a few conventions in those descriptions. We use the Courier-New/10wt font when we are referring to code or artifacts in the native JavaScript and Vjet environments. Ex:
var x = 10 ; //< Date
We use [ ] to denote optional. The [ ] are not part of the comment syntax. If [ ] are to be part of the syntax, they will be quoted. For example, in describing arrays, the [ ] are part of the syntax and would be represented as '[' and ']'.
We use choice1 | choice2 etc... where you must select one choice or the other. Ex: public | protected | private In some cases we use parentheses to enhance readability but the parentheses are not part of the syntax. Ex: (//> | //<) If ( ) are to part of the syntax, they will be quoted. For example in describing a function, the ( ) are part of the function syntax and would represented as '(' and ')'.
In any case where quotes are used, they are for clarity only and are not part of the syntax. Ex: ":", "::", "(" and ")". Italics denote a term or structure name such as Simple-Name and Function-Declaration.
Some Coding Assumptions
For some of the examples we assume that we can execute JavaScript and can output information to a console.
The examples in this document were executed in the Vjet Eclipse IDE Plugin..
vjo.sysout.println(...) is a function available to us in Vjet to do console output.
Console emitted output is preceded by a "console>" and related output follows on the following line. Example:
console>Some console output line 1
console>Some more console output...
Native JavaScript language comments
All VJETDoc are regular JavaScript comments; not all JavaScript comments however contain VJET type information. It's the structure of the comment text that makes something a VJETDoc. For a quick review here is the native JavaScript language comment syntax:
// Single line - comment stretches to end of line /* Single line */ /* Mutli-line Line1... Line2... */
VJETDoc can be single-line or multi-line.
What does a VJETDoc comment structure look like?
A VJETDoc starts with a regular JavaScript starting comment introducer:
// / /*
It is then immediately followed by (no whitespace between) a VJETDoc introducer:
< >
We then have a comment-body and normal (if any) ending comment syntax (if we are in a multi-line comment we end with */ ). The Comment-Body is where, minimally, you would place your Vjet type declaration. Optionally the Vjet type declaration could be followed by other regular JavaScript comment text. However, to denote the end of the Vjet type declaration and the start of a regular JavaScript comment text, we use a semicolon as a separator.
Top-level VJETDoc Comment Structure
Comment-Separator: ";"
A semicolon separates a VJETDoc from possible following general JavaScript code comment.
Comment-Body: Type-Decl [Comment-Separator] [any valid JavaScript comment text]
Vjet-Single-Line-Comment: (//>
| //<) Comment-Body
Vjet-Multiline-Comment: (/>
| /<
| /*>
| /*<) Comment-Body */
Vjet-Comment: Vjet-Single-Line-Comment
| Vjet-Multiline-Comment
Some examples to warm up with:
Just Vjet Decl | Vjet Declaration with a other JavaScript comment text (note the semicolon as separator) |
---|---|
//> String | //> String ; Single-line comment. The next entity is typed as a String |
//< String | //< String ; Single-line comment. The previous entity is typed as a String |
/*> String | /*> String ; Multi-line comment. The next entity is type as a String */ |
/*< String | /*< String ; Multi-line comment. The next previous is type as a String */ |
/**> String | /**> String ; Multi-line JsDoc comment. The next entity is typed as String */ |
/**< String | /**< String ; Multi-line JsDoc comment. The prev entity is typed as String */ |
Direction Matters
VJETDoc uses the < (less-than) and > (greater-than) signs following the starting section of regular JavaScript comments, to be recognized as the beginning of a VJETDoc.
The meaning of the arrows (< and >) denote the direction VJETDoc should look for a JavaScript construct to apply its type information to.
A comment starting with "//>" or "/>" or "/*>" means the comment declaration applies to the next JavaScript entity.
A comment starting with "//<" or "/<" or "/*<" means the comment applies to the previous JavaScript entity.
We support the /*> ... */ and /*< ... */ style comments for systems that treat them as JsDoc-style comments.
Later we will describe a Vjet type declaration is and what JavaScript/Vjet constructs can have type information associated with them. We already have seen a simple Vjet type declaration in the previous table. The type is String.
We could for example say a local variable, account, should be typed as a String and note that it is initialized with the id of a default account:
//> String ; we initialize to the default account id var account = "acc_def" ;
We could also write this on a single line using the //< style VJETDoc which says apply the Vjet type information to the previous JavaScript entity. In this example, it is the local variable account2.
var account2 = "acc_def" ; //< String ; we initialize to the default account id
The key from these last two examples is which VJETDoc starting sequence was used. If the entity we want to type comes after our comment we use the >. If the entity we want to type comes before our comment we use the <. We have also seen the first JavaScript entity that we can apply type information to. In this case it was a local variable.
Mixing VJETDoc and JavaScript code comment
Commenting is always to be encouraged in your code. The VJETDoc syntax allows you to have traditional comments about your code in addition to the structured Vjet declaration. To distinguish general comments from Vjet declarations, you must end the VJETDoc declaration portion with a semicolon before beginning the general code comments. We intersperse a couple of concepts ahead of time such as function declarations and other type qualifiers like final. The point is all VJETDocs can have a type part and normal JavaScript text comment part. Here are some examples:
//> public final Number ; This is the age of the person //< void warn(String msg) ; Invokes the JS alert(...) global function /*> void reset() ; * All the members will get their initial default * values restored */ /**> public final Number ; * * We need to make sure the total tax rate does not * exceed the overall individual rate */ // We have a following VJETDoc ending in a semicolon. This is ok and is a // no-op in this case //< void work(String operation, Number occurrences) ;
Using VJETDoc with native JavaScript types
Native JavaScript supports a number of primordial types. These are the foundational types upon which everything in JavaScript is based on.
Object and Object Literal
var obj1 = new Object ; //< Object var obj2 = { } ; //< ObjLiteral; This is a synthesized type for representing object literals
Boolean and boolean
var t = true ; //< boolean var f = false ;//< boolean var T = new Boolean(true) ; //< Boolean var F = new Boolean(false) ; //< Boolean
While this seems redundant, the key is to see how these act in a control statements like if/else or while/do or case?
Number
var max = 10 ; //< Number var boil = 212.0 //< Number var rate = 31.45 ;//< Number // the following types are synthesized and all extend Number: int, short, long, float, double ==> JavaScript Number var max= 10;//< int var boil= 31.45 ;//< float var rate = 31.45 ;//< double
String
var name = 'MrP' ; //< String var name2 = new String('MrP') ; //< String // the following type char is synthesized and extends String var achar = 'f'; //< char
Date
var today = new Date() ; //< Date
Function
function add(a, b) \{ //< Number add(Number, Number) return a + b ; } //> Number add(Number, Number) ; function expression function(a, b) \{ return a + b ; }
Array
var names1 = ['Adams', 'Jefferson', 'Wilson'] ; //< Array var names2 = new Array() ; //< Array names2[0] = 'Adams' ; names2[1] = 'Jefferson' ; names2[2] = 'Wilson' ;
RegExp
var re1 = /1\2/ ; //< RegExp var re2 = new RegExp('/1\2/') ; //< RegExp
Synthesized Data Types
- int, short, long, float, double ==> JavaScript Number
- boolean ==>JavaScript boolean literal
- char ==> JavaScript String
What constructs can we type?
In a nutshell, every aspect of JavaScript is able to be typed by VJETDoc -- that's its goal. The following is a list of those areas:
Global Variables
Counter = 10 ; //< Number
Local Variables
var id = 'AX123' ; //< String
Object Literals
var person = { name: 'MrP', //< String age: 33, //< int bday: undefined, //< Date married: true //< boolean isRated: function() { //< Function return true ; } }
Object Properties
var person = new Object ; person.name = 'MrP'; //< String person.age = 33 ; //< int person.bday = undefined ; //< Date person.married = true ; //< boolean person.isRated = function() { //< Function return true ; } }
Type References
var theDateType = Date ; < type::Date var today = new theDateType ; < Date
Function Expressions
function max(a, b) {//< void max(String, Date) } var func = new Function("a", "vjo.sysout.println(a)");//< void fn(String)
Function References
var f = function(a, b) { ... } //< void fn(String,String) var f = new Function('a', 'b', '...') //< void fn(String, Date)
Statements
The for-loop and for..in statements have variables that are part of the construct. Those variables can be typed.
for(var i=0;/*<Number*/ i<10;i++){ }
// for..in loops through the elements of an Array or through the Properties of an Object. // This doesn't require a type comment since variable here will always be treated as a String for (var variable in someObject) { }
What types can I use in the VJETDoc?
So far we haven't discussed what types we can use in our VJETDocs. Vjet supports the typing of JavaScript, so it makes sense that we should be able to use native JavaScript types in our comments. We can also use any structured Vjet type as well as any native Java primitive types and a subset of the Java common reference types.
Native JavaScript types
Object, Number, String, Boolean/boolean, Date, Function, Array
VJET JS structured types
ctype(classes), itype (interface), etype (enum), mtype (mixin), otype (object literal), ftype (function instance).
There is a separate document that describes all the various structural types in Vjet JS. Suffice to say, that we can use VJETDocs to help describe the type itself and its contents.
Java Data Types
We enable the following Java types for interoperability and translate-ability between and with Java. You are not required to use these in pure native JavaScript only solutions. However, the more specific your typing is, the less errors you will have in your code.
A separate document talks about Java and JavaScript translation and interoperability as well as type mappings between the two languages/environments.
Primitives
You can use the Java primitive type names to type JS entities. The primitive set translates to JavaScript types indicated by the ==>
- int, short, long, float, double ==> JavaScript Number
- boolean ==>JavaScript boolean literal
- char ==> JavaScript String
Reference Types
The following Java reference types are usable in VJETDoc. Since we aren't yet talking about Java/JavaScript interoperability or translation, it suffices to say that the following Java types map to the following JavaScript types:
- java.lang.Object ==> JavaScript native Object
- java.lang.String ==> JavaScript native String
- java.util.Date ==> JavaScript native Date
Type Names
We already identified a number of possible type names (JavaScript native types as well as some Java ones). However, these are types that we ourselves did not create. In VJET JS we can create different types ourselves. The description for how to create Vjet types is in another document but we mention it here, now, for completeness. What follows is the syntax allowed for Vjet type names.
Simple-Name: A Simple-Name must conform to a valid JavaScript variable name.
Ex: String, Number, Date (such as JavaScript built-ins) or Person, TaxRate (from simple Vjet type names).
Note that a valid JavaScript variable name excludes reserved JavaScript keywords.
Qualified-Name: Dot delimited Simple-Name's
Ex: work.Rating, personnel.records.EmploymentHistory.
There should be no white space between the Simple-Name and the dot's.
Limited-Type-Name: Simple-Name | Qualified-Name
Type-Name: Limited-Type-Name
| "void"
We include void for when we are dealing with typing return types from functions; this is the only place it's used. We will discuss how to type functions themselves later on.
We can think of dot-delimited names as a way to better structure our types into meaningful groups. In Vjet we call this grouping a namespace. This concept also exists in other languages such as Java (packages) and C++ (namespaces).
We include some simple Vjet types just to see where the type name comes into play. We use the names from the previous examples.
vjo.ctype('TaxRate') // A no namespace type // An empty class declaration .endType(); vjo.ctype('work.Rating') // An empty class declaration .endType(); vjo.ctype('personnel.records.EmploymentHistory') //< public // An empty class declaration .endType();
A brief note on name-space and VJET type naming conventions: Generally name-spaces are represented in lower case and types start with an upper case and are camel-case after the first letter. So when we say type name, we should use the aforementioned definition.
Type Reference
JavaScript allows you to assign, refer to, pass as arguments or event return from a function types themselves. Vjet provides a way to type such a reference. Unsurprisingly, it's called a Type Reference.
The following structure defines a type reference:
Type-Reference: "type:" Limited-Type-Name
We provide the following examples to show the use of a Type Reference.
var theTypeDate = Date ; //< type::Date var today = new theTypeDate ; //< Date
Note the difference in the declarations. When we want to assign the JavaScript native type Date to a variable, we are talking about a reference to Date, hence a type reference. When we are talking about an instance of Date, like what is in the variable today we just use the type Date to declare it. In JavaScript, a type can have properties as well as prototypical properties. With a type reference, you would be able to access that types properties but not its prototypical properties. When using just a type-name, we get access to its prototypical properties but not the type's properties.
vjo.ctype('bar.Per') .protos({ name: undefined, //< String age: undefined, //< int //> constructs(String name, int age) constructs: function(name, age) { this.name = name ; this.age = age ; } }) .endType(); function out(msg, o) { vjo.sysout.print(msg + ": "); vjo.sysout.println(o); } var theTypeObject = Object; //< type::Object var obj = new theTypeObject; //< Object var theTypeDate = Date ; //< type::Date var today = new theTypeDate; //< Date var theTypeNumber = Number ; //< type::Number var num = new theTypeNumber(3) ; //< Number var theTypePers = bar.Per ; //< type::bar.Per var person = new theTypePers('MrP', 33) ; //< bar.Per out('obj', obj) ; out('today', today) ; out('num', num) ; out('age', person.age) ;
console> obj: [object Object]</nowiki> today: Sat Jan 22 2011 15:25:56 GMT-0800 (PST) num: 3.0 age: 33.0
Type references require an active needs when they type itself is actually being used (ie its being new'ed or a property is being accessed on it, etc...).
Where can we apply VJETDoc typing?
There are many aspects in JavaScript one might need to declare. The list includes general native JavaScript constructs as well as VjO specific constructs:
- Local variables
- Global variables
- Object properties
- Object literals
- Arrays
- Loops
- Functions (declaration and expression)
- Vjet types (ctype, etype, itype, mtype, otype, and ftype) themselves and their internals
Below are some quick examples:
MAX_AGE = 130 ; //< Number ; this is a global var winnerDays = [3, 11, 17, 23, 29] ; //< Number[] var person = { name: 'MrP', //< String age: 33, //< int married: true, //< boolean bday: new Date('01/01/1970') //< Date } ; var person = new Object ; person.name = 'MrP' ; //< String person.age = 33 ; //< int person.married = true; //< boolean //> boolean isNewYearBaby(Date date) ; we type the functions signature function isNewYearBaby(date) { return date.getDay() == 0 && date.getMonth() == 0 ; } var f = isNewYearBaby ; //< Function ; f is a function