Jump to: navigation, search

VJET/VJO Language Ref

Purpose

The purpose of this document is to capture the references that are implemented in the code base. This simply provides the specs for the implemented VJO language features.

Overview

This document provides details of the individual elements of VJO language features. The VJO code comments are briefly explained in this document but complete references are available in a separate document.

It covers all the different types supported and elements of each type.

Definition

A simple definition of VJO is, it's a structured version of JavaScript that is similar to Java Class. Even though native JavaScript has some of the desired notions like inheritance etc, VJO formalizes those.

VJO Types

Below is the list of fundamental VJO types that are supported.

  1. CType – Class type, similar to Java Class
  2. IType – Interface type, similar to Java Interface
  3. EType – Enum type, similar to Java Enum
  4. MType – Mixin type, a code template that can be mixed into any of the avove types.
  5. OType – Typed object literal type. JavaScript provides on the fly object through literal and otype formalizes the definitions of those object literal types.
  6. Nested Type – A VJO type within another VJO Type, similar to Java inner classes.


Elements of VJO Type

Following is the list of elements that each VJO type consists with some exceptions. The definition of each element won't change for these elements in the later part of the document but may differ in meaning for each type.


Semantic
VJO Syntax
Notes
Type decleration
vjo.ctype('a.b.MyType')
“a.b” represents package name and “MyType” represents the name of the type
Needs:

Dependent declaration

vjo.ctype('a.b.MyType')
.needs('x.y.SomeOtherType')

or

.needs(['x.y.SomeOtherType1', 'x.y.SomeOtherType2'])
Needs construct defines the dependent type's full name. In this case, “a.b.MyType” has dependency on “x.y.SomeOtherType”.

Note: Even if the dependent types are references using full name, it still have to be declared with needs before using it.

Satisfies:

Interface contract

vjo.ctype('a.b.MyType')
.satisfies('a.b.IMyType')

or

.satisfies(['a.b.IMyType1', 'a.b.IMyType2',])
Satisfies construct defines the name of the VJO itype that this VJO type satisfies. In this case, “a.b.MyType” satisfies interface contract the itype “a.b.IMyType”. There is no need to declare the itype as dependent explicitly using “needs”.
Expects:

Expected interface contract to mixin an mtype

vjo.mtype('a.b.MyType')
.expects('a.b.IMyType')
Expects is only applicable for mtype. The resulting type that mixes in this mtype should have the implementation for this itype, through combined implementation in mtype and the target ctype.

There is no need to declare the itype as dependent explicitly using “needs”.

Inherits:

Inheritance

vjo.ctype('a.b.MyType')
.inherits('a.b.MySuperType')

or

.inherits(['a.b.MySuperType1', 'a.b.MySuperType2',])
Inherits construct defines the name of the super class VJO type. In this case, “a.b.MyType” in inherited from “a.b.MySuperType”.

There is no need to declare the itype as dependent explicitly using “needs”.

Mixin:

Mixin an mtype

vjo.ctype('a.b.MyType')
.mixin('a.b.MyMType')

or

.mixin(['a.b.MyMType1', 'a.b.MyMType2',)
Mixin provides a way to mix-in a code template that is declared as mtype.

There is no need to declare the itype as dependent explicitly using “needs”.

Props:

Static members section

vjo.ctype('a.b.MyType')
.props({
    //Declare static members here
})
Props section is where you define all the static members of the type.
Protos:

Instance members section

vjo.ctype('a.b.MyType')
.protos({
    //Declare instance members here
})
Protos section is where you define all the instance members of the type.
Inits:

Initialization section

vjo.ctype('a.b.MyType')
.protos({
})
.inits(function () {
//Add code for initialization
})
Inits section provides a window for you to add some logic where it's guaranteed that type is ready and no one used it yet. Generally used for initialization at the type level(not instance level).
Type Options:

Options for type definition

.options({
    autoConstruct: true
})
Options that are used during the initialization of the type.

Refer to “Type Options” section for more details

endType:

Type closure.

vjo.ctype('a.b.MyType')
.protos({
})
.endType();
Every type must end with “endType()” statement. Without this, the type is not considered complete.


Access Control and Modifiers

The following table shows where access modifiers, abstract and final are allowed.

public protected default private abstract final
ctype * * * *
etype * *
itype * *
otype * *
mtype * *
member * * * * *
method * * * * * *


Structure of the declarations

The Vjet types have an order of appearance and a number of times they may appear. This list shows the order of appearance from top to bottom in the table. Each entry specifies the number of occurrences of the section allowed in the type declaration.


Section
Class Type(CType)
Interface Type(IType)
Enum Type(EType)
Mixin Type(MType)
Object Literal Type(OType)
VJO-type .ctype (required) .itype (required) .etype (required) .mtype (required) .otype (required)
.needs 0..n 0..n 0..n 0..n NA
.defs NA NA NA NA 1 (required)
.values NA NA 0…1 NA NA
.inherits 0…1 0…n NA NA NA
.satisfies 0..n NA 0..n 0…n NA
.expects NA NA NA 0…1 NA
.mixin 0...n NA 0...n NA NA
.props 0…1 0...1 0...1 0...1 NA
.protos 0...1 0...1 0...1 0...1 NA
.inits 0...1 0...1 0...1 NA NA
.options 0...1 NA NA NA NA
.endType 1 (required) 1 (required) 1 (required) 1 (required) 1 (required)

NA – Not applicable

0…1 – Up to 1 is allowed.

0…n – 0 to n number of occurrences allowed


Order of the sections

This section explains the required order of the above sections in a type.

This order applies to all the types. If a section that is specified is not applicable to a type, skip to the next one.

Vjo.ctype Vjo.etype Vjo.mtype Vjo.itype Vjo.otype
Any Order
needs (0…*)
inherits (0…1)
mixin (0…*)
satisfies (0…*)
Any Order
needs (0…*)
satisfies (0…*)
Any Order
needs (0…*)
satisfies (0…*)
Any Order


needs (0…*)
satisfies (0…*)
defs(0…1)
Any Order


props (0…1)
protos (0…1)
values (0…1) expects(0…*) Any Order


props (0…1)
protos (0…1)
endType(1…1)
inits (0…1) Any Order


props (0…1)
protos (0…1)
Any Order
props (0…1)
protos (0…1)
inits (0…1)
options(0…1) inits (0…1) options(0…1) options(0…1)
endType(1…1) options(0…1) endType(1…1) endType(1…1)
endType(1…1)


VJO Comments

VJO defines a structured JavaScript comments to declare modifiers and/or structure of the VJO statements. More detailed information about the comments are in separate document.

Since there is no way to declare modifiers etc in JavaScript, you can declare those using VJO comments. These VJO comments are almost like meta data about the logical code block like member or statement.

Type level VJO Comments

You can specify the type level modifier using VJO comments like below.

vjo.ctype('a.b.MyType') //< public
.protos({
 
})
.endType();

Member level VJO Comments

vjo.ctype('a.b.MyType') //< public
.protos({
    //> public void myMethod(String param1, int param2, MyType aram3)
    myMethod : function (param1, param2, param3) {
 
}
})
.endType();


Needs (Dependency declaration)

Below is the syntax for declaring a dependency.

Syntax 1:

.needs('<type name>', ['alias'])

Syntax 2:

.needs(['<type name 1>',' <type name 1>'])

The Syntax 1 provides a way to alias a dependency and Syntax 2 provides a way to declare multiple dependencies using one needs call.

Duplicate simple names

Since VJO provides shortcuts to reference dependency types using “[#_this.vj$: this.vj$]”, you would have to use alias if you have a situation where two separate dependencies have same simple name.

Following examples show how you can declare those dependencies.

Invalid:

.needs('vjo.dsf.document.Image')
.needs('vjo.samples.images.Image')

In above example, there is no way to reference second dependency.

Valid:

There are two valid ways to declare above:

.needs('vjoPro.dsf.document.Image')
.needs('vjoPro.samples.images.Image', '')

In above example, the second dependency would have to be referenced using full name and cannot be referenced using this.vj$

.needs('vjoPro.dsf.document.Image')
.needs('vjoPro.samples.images.Image', 'ImageAlias') //Use Alias

In this example, the second dependency uses alias and can be references using alias with the help of this.vj$.

Properties

Below is the syntax for declaring a property. This property becomes a static member of the type if declared in props section and becomes instance member if declared in protos section.

Note that each property should only have one VJO comment, either before the statement or after the statement. Please refer to VJO comments document for details on comments direction.

Each property should be separated with a comma. In other words, the members of each section(props or protos) should follow native JavaScript object literal syntax.

[//>{VJO Forward direction Comment}]

<property name> : <property initial value>, [//<{VJO backward direction Comment}]

Examples:

my_static_property1 : undefined, //< public String
//> public int
my_static_property2 : undefined,

When defining properties, only default values using literals or JavaScript native values/objects should be used as property values. Any use of expressions that rely on other members of the type would fail.

Generally, any use of expressions is discouraged.

Refer to property initialization topics in Props/Protos section for more details.

Methods

Below is the syntax for declaring a method. This method becomes a static member of the type if declared in props section and becomes instance member if declared in protos section.

Each method can have either one VJO comment to declare the definition of the method, or more to define overloaded. Please refer to VJO comments document for more details.

Each method should be separated with a comma. In other words, the members of each section(props or protos) should follow native JavaScript object literal syntax.

[//>{VJO Forward direction Comment} …]

<method name> : function () { [//<{VJO Forward direction Comment} …]


}


Examples:

// Regular method
//> public void myMethod(String param1, int param2)
myMethod : function (param1, param2) {
 
},
 
//Overloaded method
//> public boolean myOverloadedMethod();
//> public boolean myOverloadedMethod(int count);
//> public boolean myOverloadedMethod(int count, String title);
myOverloadedMethod : function () {
 
}

Note: Initializing the methods using Function object is not supported at this time. So following would fail in VJET. This applies to both props and protos section

//> public void myMethod()
myMethod : new Function(return true)

Constructors

Constructor follows the same rules as Method above except it has the name “constructs” and it can only be in protos section.

Syntax:

[//>{VJO Forward direction Comment} …]

constructs : function () { [//<{VJO Forward direction Comment} …]

}

Examples:

Regular constructor:

//> public void constructs (String param1, int param2)
constructs : function (param1, param2) {
 
},

Overloaded constructor:

//> public boolean constructs();
//> public boolean constructs(int count);
//> public boolean constructs(int count, String title);
constructs: function () {
 
}

Props Section

Props section is where you define all the static members of the type. This includes static methods and properties. VJO comments needs to be used for modifiers.

The code that's written in props methods needs to keep in mind that they are static and generally follow the same rules as Java. For example, referring to an instance member from props method would be invalid and throw errors at run time.

Property initialization

When defining properties, only default values using literals or JavaScript native values/objects should be used as property values. Any use of expressions that rely on other members of the type would fail. Generally, any use of expressions is discouraged.

The initialization of properties using expression must be done in inits section.

Valid:

.props({
    s_prop1 : 0,
    s_prop2 : 1
})

Invalid:

.props({
    s_prop1 : 0,
    s_prop2 : s_prop1 + 1,
})

s_prop2 initialization in above example would fail. The initialization of s_prop2 must be moved to inits section as shown below.

vjo.ctype('a.b.MyType') //< public
.props({
    s_prop1 : 0,
    s_prop2 : undefined,
})
.inits(function () {
    this.s_prop2 = this.s_prop1 + 1;
})
.endType();

Protos Section

Protos section is where you define all the instance members of your type. This includes a constructor, properties and methods.

Property initialization

When defining properties, only default values using literals or JavaScript native values/objects should be used as property values. Any use of expressions that rely on other members of the type would fail. Generally, any use of expressions is discouraged.

The initialization of properties using expression must be done in the constructor.

Valid:

.protos({
    m_prop1 : 0,
    m_prop2 : 1
})

Invalid:

.protos({
    m_prop1 : 0,
    m_prop2 : m_prop1 + 1,
})

m_prop2 initialization in above example would fail. The initialization of m_prop2 must be moved to constructor as shown below.

vjo.ctype('a.b.MyType') //< public
.protos({
    m_prop1 : 0,
    m_prop2 : undefined,
    constructs : function () {
        this.m_prop2 = this.m_prop1 + 1;
    }
})
.endType();

Type Options

This is the section where you set the values for type options. These options are used while initializing the definition of the type.

Only one options parameter (autoConstruct) is supported at this time.

Syntax

.options({
    autoConstruct: true
})

autoConstruct

Set true/false to this param to allow or not allow instantiation of the type without “new” keyword.

Default value is true.

If true, following is valid statement and right side of the expression returns an instance of the type a.b.MyType. It has same effect as instancing MyType with 'new' keyword.

var obj = a.b.MyType();

If false, you must use 'new' keyword to get an instance of the type a.b.MyType.

CType

VJO CType is similar to Java class. It's a VJO type that provides platform to define the structure of your object definition.

It consists of following sections. Look at section 5 to see how each section is declared.

  • needs
  • inherits
  • satisfies
  • mixin
  • protos
  • props
  • inits

All of the above are optional and doesn't have to be in specific order (but above is the preferred order).

Declaration:

Syntax:

vjo.ctype('a.b.MyType') //< public

where “a.b.MyType” is the fully qualified name of the ctype and VJO comments are used to declare modifiers.

Abstract ctype:

A CType can be declared abstract using VJO comments.

Following is the syntax for declaring a CType abstract. See more details in VJO_Comments.doc.

vjo.ctype('a.b.MyType') //< public abstract

Methods in an abstract ctype can be declared abstract as well. Abstract methods are only allowed in protos section. Following is an example for abstract method.

vjo.ctype('a.b.MyType') //< public abstract
.protos({
    //> public abstract void requireImpl(String s) 
    requireImpl : vjo.NEEDS_IMPL
})
.endType();

Inherits:

CType can only inherit from other ctype. So inherits call needs to points to only a valid ctype.

Constructor:

A constructor can be declared in protos section but not mandatory. Not defining a contractor is same as defining a contractor with no parameters and nothing in the body.

Instantiation of VJO Type:

Instantiating a ctype is same as native JavaScript, you simply use “new” to instantiate it.

var obj = new a.b.MyType(100, 200);

Apart from native JavaScript syntax, VJO also provides instantiating the objects without 'new' keyword. Rules apply, refer to [#_Type_Options Type Options] section.

Following has same effect as above example.

var obj = a.b.MyType(100, 200);

More examples:

var obj = new this.vj$.MyType(100, 200); //<MyType
var obj = this.vj$.MyType(100, 200); //< MyType
var obj = new this(100, 200); //< MyType; (applicable only in props block)
var obj = this(100, 200); //< MyType; (applicable only in props block)

Note that MyType can be referenced in various different ways, refer to [#_this.vj$: this.vj$] topic in [#_Special_keywords Special Keywords] section for more details.

Rules:

The following rules apply to VJO ctype:

  • Can be defined as abstract
  • Can be used to create new instances unless it's an abstract. Refer to VJO comments documents to see how to declare a ctype abstract/
  • Can be a base type(super type) for other ctypes (inheritance)
  • Can extend from another single base type (inheritance)
  • Can implement an itype (interface)
  • Can control accessibility using access modifiers
  • Can create nested classes
  • Can create anonymous classes
  • Can declare static and instance members/functions

Access

When no access is specified on the type the default access is public

Example:

vjo.ctype('a.b.MyType') //< public
.props({
    RATE: 2.45
})
.protos({
    amount: 0,
    balance: 0,
    constructs : function (val1, val2) {
       this.amount = val1;
       this.balance = val2;
    },
 
    getAmount : function () {
        return this.amount;
    },
 
    getBalance : function () {
       return this.balance;
   }
})
.endType();

IType

VJO IType is an interface type which is similar to Java interface. As you may already know, interface cannot have implementation so same rule applies to itype.

IType doesn't have much bearing at runtime except to verify if the satisfying type has the methods implemented during the type initialization of that type. Apart from that, you can also refer to the static final properties of the itype.

It consists of following sections. Look at section 5 to see how each section is declared.

  • needs
  • inherits
  • protos
  • props
  • inits

All of the above are optional and doesn't have to be in specific order (but above is the preferred order).

It has inits section but it can only be used for initializing static variables.

An itype can be implemented by a ctype, abstract ctype, or etype, using the .satisfies section.

Declaration:

Syntax:

vjo.itype('a.b.IPerson') //< public

where “a.b.IPerson” is the fully qualified name of the itype and VJO comments are used to declare modifiers.

Props section:

This section has limitations for itype. It only allows static final(constants) variables and inner types.

Inherits:

IType can only inherit from other itype. So inherits call needs to points to a valid itype. It allows inheriting from more than one IType. Refer below section for more details.

Access

When no access is specified on the type the default access is public

Syntax

Apart from regular inherits syntax (Refer to “Elements of VJO Type” section), IType also supports following syntax.

vjo.itype('a.b.MyType') //< public
.inherits(['a.b.IType1', 'a.b.IType3'])
.endType()

It allows multiple inherits types. Of course, these types must be another ITypes.

Following is the list of valid syntaxes:

.inherits('a.b.IType1')

or

.inherits(['a.b.IType1', 'a.b.IType3'])

or

.inherits('a.b.IType1')
.inherits('a.b.IType3')

Allowed constructs:

Since itype is an abstract type, it only allows following.

  • Constants
  • Public method definitions (with no implementation)

Methods in props section are not allowed.

Example:

vjo.itype('a.b.IPerson') //< public
.props({
    DEFAULT_ID:0 //< public final int
})
.protos({
    //> public void getName()
    getName: vjo.NEEDS_IMPL
})
.endType();

vjo.NEEDS_IMPL is a global constant that can be used for declaring an abstract method. Just by using this doesn't make a method abstract, method declaration has to specify “abstract” using VJO comments.

More details in vjo.NEEDS_IMPL section under “[#_vjo.NEEDS_IMPL Special Keywords]”.

MType

VJO MType, or a mixin type, consists of same elements as of CType but it works like a code template. In other words, it doesn't have any context on its own and it gets the context of the target type that it's mixed into.

If we look at a set of properties and functions/methods that belong together but don't necessarily constitute a class, you could call that a mixin.

All though it works like a code template, it still has the namespace in VJO.

It consists of following sections. Look at section 5 to see how each section is declared.

  • needs
  • satisfies
  • expects
  • protos
  • props

All of the above are optional and doesn't have to be in specific order (but above is the preferred order).

It also did not have inits section because it has no implementation so no initialization section.

Declaration:

Syntax:

vjo.mtype('a.b.PersonUtil') //< public

where “a.b.PersonUtil” is the fully qualified name of the mtype and VJO comments are used to declare modifiers.

Satisfies:

Vjo.mtype.satsifies

  • Satisfies take itype as a string or array
//> final public vjo.mtype satisfies(String type)
//> final public vjo.mtype satisfies(Array type)
  • Mixin Definition can satisfy 0…N of the of the methods declared in the IType

Partial satisfying an itype in mtype

Itype + MType with 0 methods implemented

vjo.itype('a.b.c.IFoo') //< public
.protos({
    //>public
    doIt : vjo.NEEDS_IMPL,
    //>public void doIt2(String a)
    doIt2 : vjo.NEEDS_IMPL,
    //>public String doIt3(Number a)
    doIt3 : vjo.NEEDS_IMPL
}).endType();

Partially satisfied mixin must implement 0…N of the methods declared in itype a.b.c.IFoo.

vjo.mtype('a.b.c.MyMixin')
.satisfies('a.b.c.IFoo')
.protos({
    //>public doIt()
    doIt : function(){
        alert("test");
    }
}).endType();

Target ctype a.b.c.MyTargetType must satisfy the a.b.c.IFoo contract only methods doIt2 and doIt3 must be implemented to complete the missing methods that were not satisfied in Mtype. If all methods doIt, doIt2, and doIt3 are not implemented then there is an error. Implemented here means access is not reduced, return type and argument types match.

vjo.ctype('a.b.c.MyTargetType') //< public
.mixin('a.b.c.MyMixin')
.protos({
    //>public void doIt2(String a)
    doIt2 : function(a){
 
    },
    //>public String doIt3(Number a)
    doIt3 : function(a){
        return null;
    }
})
.endType();

The Target type has the burden of implementing all the methods.

Expects:

Expects takes an IType or Ctype

//> final public vjo.mtype expects(String type)

Expects is different from satisfies; the list of methods and properties must be implemented in the target type. When using the mtype the methods and properties are assumed to be available.

The access for each property and method can have the following modifiers redefined:

Access

Final

All methods and properties must be implemented in the target type

There is no runtime binding when using expects. You can not do any instance of checks on the target type unless the target type implements an interface or satisfies an interface directly.


Example of expects using itype

Itype with methods that must be implemented

vjo.itype('a.b.c.IFoo') //< public
.protos({
    //>public
    doIt : vjo.NEEDS_IMPL,
    //>public void doIt2(String a)
    doIt2 : vjo.NEEDS_IMPL,
    //>public String doIt3(Number a)
    doIt3 : vjo.NEEDS_IMPL
})
.endType();

MType with 1 method implemented (mtype can implement 0…N of the expected methods)

vjo.mtype('a.b.c.MyExpectsMixin') //< public
.expects('a.b.c.IFoo')
.protos({
    //>private
    foo : function(){
        this.doIt();
        this.doIt2("test");
        this.doIt3(33);
    }
})
.endType();

Ctype with remaining methods – note the access is not public.

vjo.ctype('a.b.c.MyTargetExpectCtype') //< public
.mixin('a.b.c.MyCtypeExpectedMixin')
.props({
    MMM:10, //<Number
    NNN:"test", //<String
    //>public void main(String... args) 
    main : function(args){
    this().foo(); // method that was mixed in
}
})
.protos({
    //>public
    doIt : function(){
        vjo.sysout.println("doIt");
    },
 
    //>private final void doIt2(String a)
    doIt2 : function(a){
        vjo.sysout.println("doIt2");
    },
 
    //>private final String doIt3(Number a)
    doIt3 : function(a){
        vjo.sysout.println("doIt3");
        return "test";
    }
}).endType();

Example of expects using ctype

Foo ctype which is expected by our mtype

vjo.ctype('a.b.c.Foo') //< public
.props({
    MMM:10, //<public Number
    NNN:"test" //<public String
})
.protos({
    //>public void doIt(String) 
    doIt : function(){
    },
    //>public String doIt(Number) 
    doIt2 : function(){
        return "";
    }
})
.endType();

Mtype with one property and one method from expects type

vjo.mtype('a.b.c.MyCtypeExpectedMixin') //< public
.expects('a.b.c.Foo')
.protos({
    //>public void foo() 
    foo : function(){
        this.doIt();
        //this.doIt2();
        var x= this.type.MMM + 2;
        vjo.sysout.println(this.type.NNN);
    }
}).endType();

Target Ctype implementing on property and one method from expect type a.b.c.Foo

vjo.ctype('a.b.c.MyTargetExpectCtype') //< public
.mixin('a.b.c.MyCtypeExpectedMixin')
.props({
    NNN:"Foo", //<String 
    MMM:111
})
.protos({
    //>private String doIt(Number) 
    doIt2 : function(){
        this.foo();
        return "";
    }
}).endType();

Access

When no access is specified on the type the default access is public

Example:

vjo.mtype('a.b.MyMType')
.satisfies('a.b.IPerson')
.expects('a.b.IPerson')
.props({
    //> public void util(int i)
    util : function (i) {
 
    }
})
.protos({
    //> public int getCount
    getCount : function () {
        return 10;
    }
})
.endType();

Target ctype that mixes-in the above mtype

vjo.ctype('a.b.MyType') //< public
.mixin('a.b.MyMType')
.protos({
    //> public String getName()
    getName : function () {
        return "John Doe";
    }
})
.endType();

MyType only defines getName method but due to mixing in MyMType, it now also gets util and getCount methods.

Instance Level Mixin:

A mixin can be used with an instance. The above example shows how to mixin an mtype to a type, it's also possible to mixin an mtype for a specific instance instead of the whole type.

Following example illustrates how to mixin at instance level.

var obj = new a.b.SomeType();
vjo.mixin('a.b.MyMType', obj);
alert(obj.getName());

vjo.mixin is a global utility method and it expects fully qualified name of the mtype and the target object.

Accessing target Type:

Since mtype is a template, doesn't have context and gets the context of the target type that it gets mixed into, there is no easy way to refer to the type it's going to be executed.

In order to address this issue, VJO provides this.vj$.type and that refers to the type this mtype got mixed into using mixin method.

Refer to Special key words section for more details.

EType

VJO EType, or an enum type, works much like Java enum. All etypes implicitly inherit from vjo.Enum (pre-defined) abstract type. No type can explicitly inherit from vjo.Enum.

It consists of following sections. Look at section 5 to see how each section is declared.

  • needs
  • satisfies
  • protos
  • props
  • inits
  • values

All of the above are optional.

Structurally it is same as ctype except the constructor is private and it also has values section. So it can have props and protos section with methods and properties. It can also have contractor.

Essentially etypes are ctypes with very specific rules and constructs.

Rules that are specific to enum:

  • An etype cannot be instantiated explicitly.
  • Can be declared as public or default onlyy; not private or protected.
  • Enum constants are final
  • Definition is final; cannot be extended (subclassed)
  • Constructor access must be private or default
  • Enum cannot be extended or inherited from another VJO type.
  • Can be nested in other types or nesting of other types in it are allowed.

Declaration:

Syntax:

vjo.etype('a.b.Day') //< public

where “a.b.Day” is the fully qualified name of the etype and VJO comments are used to declare modifiers.

Access

When no access is specified on the type the default access is public

values construct:

values construct is where you define enum values. VJO supports two types of syntax for values section.

Syntax #1:

.values('ENUM1, ENUM2, ENUM3')

This syntax simply creates 3 enum values with labels ENUM1, ENUM2, and ENUM3.

Example:

vjo.etype("a.b.Day")
.values("MON,TUE,WED,THU,FRI,SAT,SUN")
.endType();

To access an enum value, you simply refer just like how you would access a static property(a.b.Day.MON). Each enum value is an object of it's etype.

Syntax #2:

.values({
    ENUM1 : [paramValue1, paramValue2,],
    ENUM2 : [paramValue1, paramValue2,],
    ENUM3 : [paramValue1, paramValue2,]
})

The above syntax requires that this enum contain a constructor that takes in params defined in above syntax. Left side provides the label and right side provides array of arguments for constructor.

Accessing the enum values is same in both syntaxes.

Example:

vjo.etype("a.b.Day")
.satisfies("a.b.IDay")
.protos( {
    m_value : false,
    m_displayName : "Unknown",
    //> public String m_msg
    m_msg : "Test", 
    //> private void contructs(boolean, String)
    constructs : function (val, displayName) { 
        this.m_value = val;
        this.m_displayName = displayName;
    },
 
    //> public boolean isWeekday()
    isWeekday : function () { 
        return this.m_value;
    },
 
    //> public String getDisplayName()
    getDisplayName : function () {
        return this.m_displayName;
    }
} 
)
.values({
    MON:[true, "Monday"],
    TUE:[true, "Tuesday"], 
    WED:[true, "Wednesday"], 
    THU:[true, "Thursday"],
    FRI:[true, "Friday"], 
    SAT:[false, "Saturday"],
    SUN:[false, "Sunday"]
})
.endType();

Usage:

Usage of the enum values is same as Java.

Example:

a.b.Day.MON
a.b.Day.MON.getName() //returns “MON”
a.b.Day.MON.ordinal() //returns 0

values method:

All etypes provide values method by default. It returns an array copy of all the enum values in that type.

a.b.Day.values() returns an array copy of all the enum values in a.b.Day.

name method:

Returns the name of the enum constant exactly as it's declared. Thus it is case sensitive. It is also final.

ordinal method:

The constant value for this enum – basically its order in the enum based on declaration position and is a 0-based index. It is also final.

valueOf method:

It has two overloaded methods

valueOf(Class clz, String enumName):

This method is static and requires an etype class object and string name for enum value. It searches for the passed string name in the passed in etype class's type and returns if found. Throw an exception if not found in it's values.

valueOf(String enumName):

This method is static and requires a string name. It searches for the passed string name in this etype and returns if found. Throw an exception if not found in it's values.

compareTo method :

Compares this enum with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

Enum constants are only comparable to other enum constants of the same enum type. The natural order implemented by this method is the order in which the constants are declared.

OType

VJO OType, or an Object Literal type, is a structured way to define the definition of JavaScript Object Literals and Function Refs.

Object Literals and Functions are frequently used constructs in JavaScript; they can be assigned to variables and properties, returned by functions, and passed as arguments. Typing these constructs enforces type safe development when used in these capacities. The following example shows an otype declaration using Vjet comments to type the members. Point is comprised of two int properties, Line is comprised of two Point properties and the function SimpleLine takes two Point arguments.

It consists of following sections. Look at section 5 to see how each section is declared.

  • Defs

Members must be either an object literal or a function signature – any other definition will be an error. The following is a valid definition for an otype.

vjo.otype('samples.Shape')
.defs({
    Point: {
        x: undefined, //< int
        y: undefined //< int
    },
 
    //> public double DRAW_X(int x);
    DRAW_X : vjo.NEEDS_IMPL
})
.endType();

Usage:

Following example shows how to use the Object Literals and Function Refs that are created using above otype.

vjo.ctype('a.b.ShapeUsage') //< public
//> needs samples.Shape
.props({
    //> public boolean showShapeDetails(Shape.Point point)
    showShapeDetails:function(point){
    alert(point.x + ' X ' + point.y);
    return false;
},
 
//> public boolean plot(Shape.createLine fn);
plot : function(fn) {
    fn({x:1,y:2}, {x:10,y:20});
    return false;
},
 
//> public Shape.createLine
createLine: function''' (p1, p2) {
    //Implementation goes here
}
})
.endType();

In above example, showShapeDetails function accepts Shape Object literal from “samples.Shape” otype and 'plot' method accepts a function ref that if of type DRAW_X function definition of “samples.Shape” otype.

defs Section:

This section is where you define your Object Literal and Function Refs. Following example shows how an OType looks like.

vjo.otype('samples.Shape')
.defs({
Point: {
    x: undefined, //< int
    y: undefined //< int
},
Line: {
    start: undefined, //< Point
    end: undefined //< Point
},
 
//> public boolean isOrigin(Point pt)
isOrigin: vjo.NEEDS_IMPL, 
//> public void createLine(Point pt1, Point pt2)
createLine: vjo.NEEDS_IMPL
})
.endType();

Access Control

The otype namespace (MyTypes in the examples) can be given only public, default level access. This is the similar capability as ctype, mtype, itype and etype. We don't support friend level declarations for otypes like we do for ctype and etypes. Default access for all otypes is public.

vjo
.otype('MyTypes') // default access 
.defs({}).endType() ;
vjo
.otype('MyTypes') //< public
.defs({}).endType() ;

The otypes themselves can only be given public or default level access. Protected/Private access is not valid since otypes are not sub-classable and defining types and not behavior.

The members of an Object Literal or Function type can be public, default or private.

public
default
protected
private
Namespace
Yes
Yes
No
No
Function Type
Yes
Yes
No
No
Object Literal Type
Yes
Yes
No
No
Object Literal Members
Yes
Yes
No
Yes

Optional members in the OL type

It is possible to define certain members of the OL as optional. This is done by using a question mark (?) after the type for the member.

vjo.otype('samples.Shape')
.defs({
    Point: {
        x: undefined, //< int
        y: undefined //< int?
    }
})
.endType();

In above example, y is optional.

Only ending parameters in object literals can be optional similar to how optional arguments are allowed for only the tail end arguments.

In above example, both x and y or only y can be optional but only x cannot be optional.

Nesting OL Types in OL Types

Nesting in Object literal types is NOT supported. If you want to make Z an Otype it must be in the top level of the defs object literal.

// before
vjo.otype('samples.Shape')
.defs({
    Point: {
        x: undefined, //< int
        Z: {
            A:10 //<int
        }
    }
})
.endType();
 
// after
vjo.otype('samples.Shape')
.defs({
    Point: {
        x: undefined, //< int '''
    }
    Z: {
        A:10 //<int
    }
})
.endType();

Nested Types

Nested types are types embedded within other types, and are often used to create logical groupings of types used by one another. Outer types specify access to their nested types, increasing control over encapsulation and containment; the physical adjacency of the type definitions enhances readability and maintenance. Nested types can be categorized as follows:

  • Member Types - Declared as members of another type
  • Anonymous Types - Declared within a code block of another type and is visible only to that block; the block of code is often a method or function. An anonymous class is a local class that has not named.

Rules

The following rules apply to nested types:

  • ctype, abstract ctype, itype, and etype support nested types.
  • A nested type can be a ctype, abstract ctype, itype, or etype.
  • Outer type access is limited to public or default.
  • The nested type access can be private, public, protected, or default, allowing the outer type to control access of its nested types.
  • Nested types get copies of the dependent types specified in the .needs section of the outer type.

Namespace

The names used for inner types have slightly different rules compared to other type members like method/property.

Nested types and other members within an outer type cannot have the same name. Outer types provide a top-level namespace; members compose an inner namespace. <OuterType Name>.<Inner Type Label Name> would be the qualified name of an inner type.

User defined package name is not allowed for a member nested type.

Members with the same name, declared in the same type, will violate namespace rules.

The names of these types must be unique across…

  • Both protos and props sections
  • Multiple levels if the inner types are cascaded.
  • Local inner types.

Member Types

Member types are declared as members of the outer type:

  • Static Inner Type - A static member of the outer type; defined in the outer type's props section.
  • Instance Inner Type - An instance (prototype) member of the outer type; defined in the outer type's protos section.

Declaration Syntax

Member types are declared within the props or protos section; to declare a member type, use: MemberTypeName : vjo.<theVJOType>()

Where:

  • The member type name and definition are separated by a colon (:).
  • Begin the member type definition using vjo.ctype(),vjo.itype(),vjo.etype()

The following example declares a static and an instance member type; both are ctypes:

vjo.ctype('OuterType')
.props({
    StaticInnerTypeName : vjo.ctype()
    ...
.endType()
})
.protos({
    InstanceInnerTypeName : vjo.ctype()
    ...
.endType()
})
.endType();

Static Inner Type

Static Inner Types have access to all static members of the outer type and are accessed as static members of the outer types.

The following is a static inner type example. Note that the inner type calls outerFunc(), which is an class function declared in the outer type, using a fully qualified reference to the function.

vjo.ctype('OuterType')
.props({
    StaticInnerType : vjo.ctype()
    .protos({
        innerFunc: function() {
            vjo.sysout.println('StaticInnerType function');
            this.vj$.OuterType.outerFunc();
	}
    }).endType(),
    outerFunc : function() {
        vjo.sysout.println('OuterType function called');
    }
})
.endType();

The following example creates an instance of the inner type and executes a function defined on the type. Note that the static inner type is accessed as a class member of the outer type.

// Accessed as a class member of the outer type
var innerType = new this.vj$.OuterType.StaticInnerType(); 
innerType.innerFunc();

Instance Inner Type

Instance Inner Types have access to prototype members of the outer type, which are referenced using the this.vj$.outer keyword. Instance inner types are accessed through an instance of the outer type.

The following is an instance inner type example. Note that the inner type calls the outer type function, outerFunc(), using the keyword this.vj$.outer.

vjo.ctype('samples.OuterType')
.protos({
    InstanceInnerType : vjo.ctype()
    .protos({
        innerFunc : function() {
            vjo.sysout.println('InstanceInnerType function');
            // this.vj$.outer used for accessing outer type members
            this.vj$.outer.outerFunc(); 
        }
    })
    .endType(),
 
    outerFunc : function(){
        vjo.sysout.println('OuterType function called');
    }
}).endType();

Instance inner types are accessed through an instance of the outer type. In the following example, the inner type is accessed by first creating an instance of the outer type, then using the outer type to create an instance of the inner type. Similar to the static inner type example, the inner type instance executes a function defined on the type.

// instance of outer type
var outerType = new this.vj$.OuterType();
// use outer type to create instance of instance inner type
var innerType = new outerType.InstanceInnerType(); 
innerType.innerFunc();

Anonymous Types (vjo.make API)

This API returns an instance of an anonymous type which inherits/implements another named type, either a ctype or an itype.

If the named ctype(source type) is an abstract or itype then the definition of vjo.make has to implement those methods.

Following java implementation has the same construct.

public interface IPerson {
    String getName();
}
 
IPerson me = new IPerson() {
    public String getName() {
       return "John Doe";
    }
};

Only protos section is allowed in an anonymous VJO type.

Syntax:

vjo.make(context, sourceType, [args…])

where…

context – scope for the anonymous type needs to be created.

sourceType – Container type for this anonymous type

args – Optional params for source type constructor

Example:

var anonType = vjo.make(this, this.vj$.SourceType)
 .protos({
     getAnonTypeProp : function () {
        // get the Anonymous Type property
         vjo.sysout.println(this.getProp()); 
     },
     getSourceTypeProp : function () {
        // get the Outer Type property
        vjo.sysout.println(this.vj$.parent.getProp()); 
     }
 })
 .endType();
anonType.getAnonTypeProp();
anonType.getSourceTypeProp();

Creating Anonymous Types

Anonymous types are created using the vjo.make() function. The vjo.make() function calls the constructor of the source type, and passes the specified argument(s); anonymous types are created at runtime, based on the source type.

  • vjo.make(context, sourceType, constructorParams)
    • context - the scope of the anonymous type
    • sourceType - the source type for the anonymous type
    • parameters - parameters for the source type constructor

The following example declares an anonymous type within the function, makeAnonType(). The anonymous type declaration includes functions that access a source type property as well as a property defined on the type itself.

Local Embedded Types

Local types are created in a code block, method in most cases. These types are not available in global type space and also don't have a name. These are available only the context of the code block where it was created.

It follows the same rules as regular VJO Types except they are not available in global type space. So vjo.getType method cannot be used to access these types.

Note that the local types follow special namespace rules. More details in [#_Namespace_of_member Namespace of member types] section

Syntax

Here is how you create a local embedded VJO type.

var TypeName = {vjo.ctype declaration | vjo.itype declaration | vjo.mtype declaration | vjo.etype declaration }

Example:

vjo.ctype('a.b.MyType') //< public
.props({
    main : function () {
        //Following is a local embedded type
        var MyLocalType = vjo.ctype()
        .props({
            m_static : 1
        })
        .protos({
            m_instance : 2
        })
        .endType();
 
        var obj = new MyLocalType();
        vjo.sysout.println(MyLocalType.m_static);
        vjo.sysout.println(obj.m_instance);
    }
})
.endType();

Nested Type Summary

The following charts summarize VJO Types and access modifier usage with outer and nested types.

VJO Types as Outer and Nested Types

Outer Type
Static Inner Type
Instance Inner Type
ctype Yes Yes Yes
itype Yes Yes No
etype Yes Yes No
mtype Yes No No
otype Yes No No

VJO Anonymous Type

This chart summarizes the definition types that can used to create an anonymous type.

Anonymous Type
ctype Yes
itype Yes
etype No
mtype No
otype No

Access Control Modifiers for Outer and Nested Types

Public
Protected
Default
Private
Outer Type Yes No Yes No
Static Inner Type Yes Yes Yes Yes
Instance Inner Type Yes Yes Yes No
Anonymous Type No No No No

Following table describes the different things that are allowed in each section.

Outer Types
InnerTypes section
Ctype
Itype
Etype
Ctype
props Section
Yes
Yes
Yes
protos Section
Yes
Yes
Yes
protos Section
Yes
Yes
Yes
Itype
props Section
Yes
Yes
Yes
protos Section
No
No
No
Etype
props Section
Yes
Yes
Yes
protos Section
No
No
No
Mtype
props Section
No
No
No
protos Section
No
No
No
Otype
props Section
No
No
No
protos Section
No
No
No

Internals of VJO Types

All VJO types inherently get certain things and this section explains it.

vjo.Object:

Every VJO type is implicitly inherited from vjo.Object without specifically declaring “inherits” but you can declare it if you choose to. By choosing to declare it explicitly has no impact.

vjo.Object has similar characteristics as java's java.lang.Object and it is a qualified VJO type that's available irrespective of whether your type has needs for it. You can instantiate it if needed.

vjo.Object API:

Static methods:

  • isIntance(Object o): Answers if object o is of this type.

Instance methods:

getClass():

Answers an instance of vjo.Class that points to this type i.e., has information about this type.

hashCode():

Answers an integer hash code for the receiver. Any two objects which answer true when passed to equals method must answer the same value for this method.

equals(Object o):

Compares the argument to the receiver, and answers true if they represent the same object using a class specific comparison. The implementation in vjo.Object answers true only if the argument is the exact same object as the receiver (===).

toString():

Answers a string containing a concise and human-readable description of the receiver. Default implementation returns <Type full name>@<Hash code>

clazz Property:

Every VJO type has a static final property called “clazz”, it points to an instance of vjo.Class object that represents this Type.

isInstance method:

Signature of the method:

public static boolean isInstance(Object o)

Every VJO Type gets this method by default. It takes an object and returns if that object is an instance of this Type.

vjo.Class:

VJO Class is a class that represents the class information of a VJO type. This class won't be instantiated by external code but VJO Object would internally create an instance of vjo Class and save with the VJO type.


Methods

VjO Class supports the following instance methods:

  • getName
  • getSimpleName
  • getPackageName
  • isInterface
  • toString

getName Method

  • It returns full name of the vjo type. If the vjo type was defined as vjo.ctype(“vjo.x.y.A”) then this method returns “vjo.x.y.A”.

Example:

var name = vjoObj.getClass().getName();

Parameters:

None

Returns:

A string representing the full name including the package path. Returns null if class info not found

getSimpleName Method

Returns the simple name of the underlying class. Returns blank string if the underlying class is null. If the vjo type was defined as vjo.ctype(“vjo.x.y.A”) then this method returns “A”.

Parameters:

None.

Returns:

String representing the simple name of the class.

Example:

var simpleName = vjoObj.getClass().getSimpleName();

getPackageName Method

Returns the package name of the underlying class. If the vjo type was defined as vjo.ctype(“vjo.x.y.A”) then this method returns “vjo.x.y”.

Parameters:

None.

Returns:

String representing the package name of the class.

Example:

var simpleName = vjoObj.getClass().getPackageName();

isInterface Method

Returns a if the type is an itype or not.

Parameters:

None.

Returns:

Bolean true or false.

Example:

var isIType = vjoObj.getClass().isInterface();

toString Method

Returns a string representation of the class object. This doesn't necessarily mean that it would return all the information from that object. It is only intended for informative representation that is easy for a person to read.


This method returns name of the class plus whether its interface or class. This may need revision to use vjo types instead of class/interface.

“class vjo.x.y.A” or “interface vjo.x.y.IA”

Returns:

a string representation of the object.

'this' Keyword

The context of 'this' reference differs dramatically based on where it is. Below table explains.


Section
Points to
Properties in protos & props Points to browser window object. Note that, since protos and props sections are valid native JS object literals, they run in window context before protos/props is executed.

Following is an invalid initialization of the property.

.props({
    TypeName : this.vj$.MyType
})
.protos({
TypeName : this.vj$.MyType
Methods in props section Points to the current VJO Type
Methods in protos section Points to current instance of the VJO Type
inits section Points to the current VJO Type and not the instance.
Methods inside closures If you are using closures and have to use 'this' inside them then note that it always depends on which context the execution reaches and doesn't always be the containing type/instance.
Methods called using JavaScript native .call or .apply methods In these cases, no matter where they are located, 'this' always refers to the passed context to these methods.


Incomplete Types & Static initialization

This section describes how a type loading is completed and how static initialization blocks are triggered.

Dependents:

Generally, by the time execution reaches a type definition all of its dependent types are already loaded but at times the dependents are loaded at a later stage. In that kind of situation, a type is marked incomplete meaning its static initialization block won't be executed.

A type is marked as incomplete if its definition is not complete and/or one of or all of its dependents are incomplete. In this case, this type waits until all of its dependents are loaded before it triggers the static initialization block (inits block).

If a type is incomplete, it waits for the all its dependents are loaded. When the last dependent is loaded then this type triggers execution of inits block.

Due to this lazy initialization of the type in cases where dependents are not available yet, it is not guaranteed that inits block would be executed when execution reaches endType of a VJO Type.


Following example will display alerts in following order.

Alert 1: "Static init block of a.b.B"

Alert 2: "Static init block of a.b.A"

vjo.ctype('a.b.A') //< public
.needs('a.b.B')
.protos({
    constructs : function () {
    var a = this.vj$.B.add(1, 2);
}
})
.inits(function (){
    alert("Static init block of a.b.A");
})
.endType(); // ''This type is not complete at this stage.''
 
vjo.ctype('a.b.B') //< public
.props({
    add : function (a, b) {
        return (a+b);
    }
})
.inits(function (){
    alert("Static init block of a.b.B");
})
.endType();// ''“a.b.A” type IS complete along with “a.b.B” at this stage.''

Special keywords

this.base:

This is used for referencing the super type, similar to 'super' in Java and follows same rules as Java.

vjo.ctype('a.b.MyType') //< public
.inherits('a.b.MySuper')
.protos({
    constructs : function(name) {
        this.base(name);
    },
    getName : function() {
        return this.base.getName();
    }
})
.endType();

this.vj$:

VJO automatically provides an object “vj$” under both protos and props section that provides references to current type, dependent types(those declared using needs) and inner types. This provides shortcut to referencing the types in current type's context.

Following example provides how vj$ can be used for a different types in the context of a type.

To reference current type:

a.b.MyType //Works everywhere but too long name if the package name is long
this.vj$.MyType //Shortcut and works everywhere
this.vj$.type //Shortcut and works everywhere

To refernce a dependent type:

a.b.DependentType1 //Works everywhere but too long name if the package name is long
this.vj$.DependentType1 //Shortcut and works everywhere

Full example:

vjo.ctype('a.b.MyType') //< public
.needs('a.b.DependentType1')
.props({
    myMethod : function () {
        //To refernce current type:
        a.b.MyType //Works everywhere but too long name if the package name is long
        this.vj$.MyType //Shortcut and works everywhere
        this.vj$.type //Shortcut and works everywhere
        //Referencing a dependent type
        a.b.DependentType1 //Works everywhere but too long name if the package name is long
        this.vj$.DependentType1 //Shortcut and works everywhere
        return true;
    },
})
.endType();

Note: Even if you are referencing a dependent type using full name (a.b.DependentType1), it would still have to be declared using needs construct. Look at [#_Elements_of_VJO Elements of VJO] for more details.


this.vj$.type:

You can use this.vj$.type anywhere within VJO type implementation (methods and inits section) to reference its type. This would come in handy when you don't know what is your containing VJO Type. For example, when you are in mtype implemention you do not know the containing Type since mtype inherits the context of the target type where it's being mixed –in.

With this, following is the list of valid ways to access the containing VJO type.

vjo.ctype('a.b.MyType') //< public
.props({
    main : function () {
        //Ways to access the containing VJO Type
        a.b.MyType //Fully qualified name
        this.vj$.MyType //Using vj$ and simple name
        this.vj$.type //Without using the name of the type
    }
})
.endType();

this.vj$.outer:

This is used inside an inner type for accessing container outer(context) object. It can also be used for referencing the parent scope object when it's created using vjo.make method.

Refer to “Member Types” under “Nested Types” section for more details.

this.vj$.parent:

This is used for referencing the source type in anonymous type.


Example:

var anonType = vjo.make(this, this.vj$.SourceType)
 .protos({
     getAnonTypeProp : function () {
         // get the Anonymous Type property
         vjo.sysout.println(this.getProp()); 
     },
     getSourceTypeProp : function () {
         // get the Outer Type property
         vjo.sysout.println(this.vj$.parent.getProp()); 
     }
 })
 .endType();

In above example, this.vj$.parent represents this.vj$.SourceType.


vjo.NEEDS_IMPL

This is a global constant that points to an empty function that throws an exception when called. This is generally used for assigning to abstract methods that require implementation. Its not mandatory to use it and simply created to save resources at runtime by sharing across multiple methods that are abstract.

Also, just using this for a method doesn't automatically make that method abstract. VJO comments have to be used for declaring a method abstract.

Example

Following examples are NOT abstract methods.

//> public void nonAbstractMethod()
nonAbstractMethod : vjo.NEEDS_IMPL,
//> public void nonAbstractMethod()
nonAbstractMethod : function () {},

Following examples ARE abstract methods.

//> public abstract void abstractMethod()
abstractMethod : function () {},
//> public abstract void abstractMethod()
abstractMethod : function () {},
//> public abstract void abstractMethod()
abstractMethod : function () { alert(1); },

Having function body has no effect if it's an abstract method. It won't be executed. VJET editor should validate and make sure there is nothing in an abstract method other than code comments.

Utility Methods

Following list of utility methods are available by default. Below table gives details of the APIs

Method
Signature
Description
hitch public Function vjo.hitch(Object ctx, Function fn, Boolean openctx) Utility that creates a function reference to the method, given a ctx. openctx is a boolean, if true, it means that someone using call(...) or apply(...) who provided an alternative context to execute the function would get used otherwise if openctx was false, you can think of this functions context as being "sealed" ie not changeable in a call(...) or apply(...) usage case. Regardless of being sealed passing a hitched function to bind will do the binding no matter what.
curry public Function vjo.curry(Function fn, Object args…) Utility that creates a function closure to combine a method and a given set of arguments.
bind public Function vjo.bind(ctx, fn, Object args…) First 2 arguments are the same processing as that of hitch which is basically to set the context for the functions execution. The remaining arguments (if any) are used in the curry(...)'ing of the args. We only need a single closure to achive the bind/curry operations.
create public HTMLElement create(elementName, value) Utility to create a dom element given a tagname, and it's innerHTML
getType public Type vjo.getType(String typeName) Returns VJO type for a fully qualified type name.
make public Type vjo.make(context, sourceType, [args…])


Look at Anonymous Type section for details
isInstanceOf public boolean isInstanceOf(Object obj, Type type) Return true/false if 'obj' of type 'type' or not respectively.
createArray public Array createArray(Object defaultValue, int size…) Returns an array object with default values filled in based on dimensions. You can pass more than one param for size for multi-dimensional array.

For example, vjo.createArray(null, 3, 2, 3) returns 3 dimensional array with 3, 2, and 3 sizes with “null” as default value.

isArray public boolean vjo.isArray(Array a) Answers if 'a' is JavaScript array object or not.
vjo.sysout.println public void vjo.sysout.println(Object msg) Prints a line with message on console. It prints msg.toString() to the console.
vjo.sysout.print public void vjo.sysout.print(Object msg) Prints a message on console. It prints msg.toString() to the console.
vjo.syserr.println public void vjo.syserr.println(Object msg) Prints a line with error message on console. It prints msg.toString() to the console.
vjo.syserr.print public void vjo.syserr.print(Object msg) Prints an error message on console. It prints msg.toString() to the console.


Reserved Keywords

Table below lists out all the reserved keywords in VJO. Left side is the list of keywords and right side is the section where these keywords are not allowed.

Keywords Applies to
props, protos, inherits, prototype, inits, satisfies, mixin, _inherits, _satisfiers, singleton, isInstance, vj$ props section
constructs, getClass, _getBase, base, vj$ protos section
props, protos, _props, _protos, vj$, _expects, expects, _satisfiers, satisfies, endType With mtype
vjo.Class, vjo.Object, vjo.Enum These reserved class names and cannot be used.