Jump to: navigation, search

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

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-NameSimple-Name  |  Qualified-Name 

Type-NameLimited-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&nbsp;

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