• No results found

TiddlyCard Class System

N/A
N/A
Protected

Academic year: 2021

Share "TiddlyCard Class System"

Copied!
35
0
0

Loading.... (view fulltext now)

Full text

(1)

TiddlyCard Class System

Quick Guide & Reference

Table of Contents

1. Introduction ... 1

2. Namespaces ... 2

2.1. Creating a Namespace ... 2

2.2. Plugins and Namespace Creation ... 2

3. Classes ... 3

3.1. Supported Keywords... 3

3.2. Basic Syntax ... 3

3.3. Specialised Types... 4

3.4. Instantiation... 5

4. Interfaces ... 5

4.1. Supported Keywords... 5

4.2. Basic Syntax ... 5

4.3. Instantiation... 6

5. Enumerations ... 6

5.1. Supported Keywords... 6

5.2. Basic Syntax ... 6

5.3. Specialised Types... 7

5.4. Instantiation... 8

6. Keyword Reference... 9

6.1. Headers/Footers... 9

6.2. Modifers... 10

6.3. Annotations ... 11

6.4. Members ... 12

6.5. Others... 17

7. Stock Property Types Reference ... 21

8. Reflection API Reference ... 24

9. Example with Comments ... 33

1. Introduction

Welcome to the TiddlyCard development community! You are reading the quick guide to the TiddlyCard class system, a feature-rich object-oriented language extension for JavaScript. We have organised this document more as a reference manual to using the class system – a step-by-step guided tutorial is not available. So if you are just starting out, it might be helpful to first refer to section 9 for an example of how everything comes together in modeling a typical real-world scenario.

While we have tried to design the class system to be as similar to Java and C# as

possible, some background knowledge of JavaScript would be helpful in

understanding the differences in functionality provided. A recommended book on the

subject is “JavaScript: The Definitive Guide” by David Flanagan (O'Reilly).

(2)

2. Namespaces

Namespaces in TiddlyCard are essentially object containers. They contain references to other namespaces, classes, interfaces, enumerations and namespace-level public variables. All proper namespace containers created by the class system are instances of tc.lang.Namespace and have an attached toString() method which returns the full address of that container.

Addressing a namespace follows a hierarchical notation. For example, the namespace

"tc.app.myplugin" is a child of the namespace "tc.app", which in turn is a child of "tc".

Top-level namespaces (like "tc") are children of the global object, which itself acts like a pseudo-namespace.

2.1. Creating a Namespace

A namespace container is created with a call to tc.lang.Namespace.build. When executed, the method builds and returns the reference to the container. It takes in two important arguments.

The root argument is a reference to a namespace root from which namespace address will be built. Forcing the developer to pass in a namespace reference helps to ensure that namespaces aren't created in a location that the code does not have access to (for security). Typically, this (referring to the global object as the namespace root) or references of the form tc.app are used for root.

The addr argument is a string representing the namespace address of the container to be created, relative to the root. The method will create any parent namespaces necessary to build the path to the container specified by addr. Existing containers along the path are not modified.

For example, the following code

is roughly equivalent to:

2.2. Plugins and Namespace Creation

Namespaces for a set of code modules do not need to be explicitly created if they are encapsulated as a plugin. The plugin loader will automatically create namespaces for a set of code modules, assuming they are specified properly in the plugin descriptor.

if (typeof(this.tc) == 'undefined') this.tc = {};

if (typeof(this.tc.app) == 'undefined') this.tc.app = {};

if (typeof(this.tc.app.myplugin) == 'undefined') this.tc.app.myplugin = {};

tc.lang.Namespace.build(this, "tc.app.myplugin");

(3)

3. Classes

Classes should need no explanation for those familiar with object-oriented programming. The features provided are similar to those in Java. You can define normal, abstract, static, or final classes with instance and/or static members.

Inheriting from super-classes and implementing interfaces are also part of the feature set.

3.1. Supported Keywords

Headers/Footers: CONSTRUCTOR, EXTENDS, IMPLEMENTS, END_CLASS

Modifers: STATIC, ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY

Annotations: ANNOTE, DEPRECATED, TRACE, TRANSIENT, EVENT, DEBUG

Members: THIS, METHOD, STATIC_METHOD, FIELD, STATIC_FIELD, CONSTANT, STATIC_CONSTANT, PROPERTY, STATIC_PROPERTY, GET, SET, END_PROPERTY, CLASS, STATIC_CLASS,

ABSTRACT_CLASS, FINAL_CLASS, INTERFACE, ENUM, BITWISE_ENUM

Others: GROUP, END_GROUP, IMPORT_METHOD, IMPORT_STATIC_METHOD, IMPORT_METHODS, IMPORT_STATIC_METHODS,

IMPORT_CONSTANT, IMPORT_STATIC_CONSTANT, IMPORT_CONSTANTS, IMPORT_STATIC_CONSTANTS

3.2. Basic Syntax

A class definition is started with a call to tc.lang.Class.define. It takes in two important arguments.

The root_space argument is a solid reference to a namespace root into which the class will be installed. Forcing the developer to pass in a namespace reference helps to ensure that classes aren't installed into a location that the code does not have access to (for security). Typically, this or references of the form tc.app.myplugin

tc.lang.Class.define( root_space, name_and_path ) [ .EXTENDS( base_class ) ]

[ .IMPLEMENTS( interface* ) ] [ .CONSTRUCTOR( constructor_fn ) ]

[ [modifier]* .FIELD( field_name, field_value ) ]*

[ [modifier]* .METHOD( method_name, method_fn ) ]*

[ [modifier]* .PROPERTY( prop_name, prop_type, prop_value* ) ]*

.END_CLASS();

(4)

are used for root_space. This argument is important as it determines where the language system looks for related constructs.

The name_and_path argument is a string containing the name of the class to be created. The class name may be prefixed by a path relative to the root_space argument. For example, if root_space is tc.app and name_and_path is

"myplugin.MyClass", it is equivalant to specifying root_space as tc.app.myplugin and name_and_path as "MyClass".

When done, the END_CLASS() method must be called to complete the definition. The reference to the class function is released only at this point.

3.3. Specialised Types Abstract Class Syntax:

Abstract class definitions are started with a call to tc.lang.Class.defineAbstract.

Everything else is as per the basic syntax, except that unimplemented methods are accepted and the class cannot be instantiated unless it is sub-classed.

Static Class Syntax:

Static class definitions are started with a call to tc.lang.Class.defineStatic.

Static classes cannot be instantiated, cannot have a constructor, cannot extend other classes, and cannot implement interfaces. They can only contain static members.

Using the modifier STATIC() is redundant as any members defined are automatically assumed to be static. Static classes can be used to store utility code or constant values and these can be imported into other classes.

Final Class Syntax:

Final class definitions are started with a call to tc.lang.Class.defineFinal.

Everything else is as per the basic syntax. Final classes cannot be inherited by other classes.

tc.lang.Class.defineFinal( root_space, name_and_path ) ...

.END_CLASS();

tc.lang.Class.defineStatic( root_space, name_and_path ) [ [modifier]* .FIELD( field_name, field_value ) ]*

[ [modifier]* .METHOD( method_name, method_fn ) ]*

[ [modifier]* .PROPERTY( prop_name, prop_type, prop_value* ) ]*

.END_CLASS();

tc.lang.Class.defineAbstract( root_space, name_and_path ) ...

.END_CLASS();

(5)

3.4. Instantiation

Classes are instantiated to objects by applying JavaScript's new keyword on the class function (EG. new tc.app.myplugin.MyClass()). The language system will ensure that the constructor property of the resulting object always points to the class function which instantiated it, and not to any of its parent classes.

4. Interfaces

Interfaces are place-holders of public-only methods and properties (excluding fields) which classes implementing them must define. If a class implements an interface, it must provide a definition for every instance member of that interface. Interfaces support multiple-inheritance from other interfaces (like Java) and can contain static members as well - allowing them to act like static classes.

4.1. Supported Keywords

Headers/Footers: EXTENDS, END_INTERFACE

Modifers: STATIC, PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY

Annotations: ANNOTE, DEPRECATED, TRACE, TRANSIENT, EVENT, DEBUG

Members: THIS, METHOD, STATIC_METHOD, FIELD, STATIC_FIELD, CONSTANT, STATIC_CONSTANT, PROPERTY, STATIC_PROPERTY, GET, SET, END_PROPERTY, CLASS, STATIC_CLASS,

ABSTRACT_CLASS, FINAL_CLASS, INTERFACE, ENUM, BITWISE_ENUM

Others: GROUP, END_GROUP, IMPORT_METHOD, IMPORT_STATIC_METHOD, IMPORT_METHODS, IMPORT_STATIC_METHODS,

IMPORT_CONSTANT, IMPORT_STATIC_CONSTANT, IMPORT_CONSTANTS, IMPORT_STATIC_CONSTANTS

4.2. Basic Syntax

An interface definition is started with a call to tc.lang.Interface.define. It takes in two important arguments.

The root_space argument is a solid reference to a namespace root into which the tc.lang.Interface.define( root_space, name_and_path )

[ .EXTENDS( super_interface* ) ] [ [modifier]* .FIELD( field_name ) ]*

[ [modifier]* .METHOD( method_name ) ]*

[ [modifier]* .PROPERTY( prop_name, prop_type ) ]*

.END_INTERFACE();

(6)

interface will be installed. Forcing the developer to pass in a namespace reference helps to ensure that interfaces aren't installed into a location that the code does not have access to (for security). Typically, this or references of the form tc.app.myplugin are used for root_space. This argument is important as it determines where the language system looks for related constructs.

The name_and_path argument is a string containing the name of the interface to be created. The interface name may be prefixed by a path relative to the root_space argument. For example, if root_space is tc.app and name_and_path is

"myplugin.MyInterface", it is equivalant to specifying root_space as tc.app.myplugin and name_and_path as "MyInterface".

When done, the END_INTERFACE() method must be called to complete the definition.

The reference to the interface function is released only at this point.

4.3. Instantiation

Interfaces can be instantiated to 'mask' objects by applying JavaScript's new keyword on the interface function and passing in an object implementing the interface (EG. new tc.app.myplugin.MyInterface(obj)). The mask created will be a proxy to the original object, exposing only the methods and properties defined on the interface.

5. Enumerations

An enumeration is a set of items with unique identifiers, each mapping to an integer value. Items from an enumeration can be used in both string and arithmetic operations (they implement both the toString() and valueOf() methods). They can also be type-checked for safety (i.e tc.demo.Language.ENGLISH instanceof tc.demo.Language == true). Iterating though the items in an enumeration set can be done using the foreach(fn, scope) method on the enumeration function.

5.1. Supported Keywords Headers/Footers: END_ENUM

Annotations: ANNOTE, DEPRECATED Members: THIS, ADD

5.2. Basic Syntax

tc.lang.Enum.define( root_space, name_and_path ) [ .ADD( name [, value ]* ) ]*

.END_ENUM();

(7)

A non-anonymous enumeration definition is started with a call to tc.lang.Enum.define. It takes in two important arguments.

The root_space argument is a solid reference to a namespace root into which the enumeration will be installed. Forcing the developer to pass in a namespace reference helps to ensure that enumerations aren't installed into a location that the code does not have access to (for security). Typically, this or references of the form tc.app.myplugin are used for root_space.

The name_and_path argument is a string containing the name of the enumeration to be created. The enumeration name may be prefixed by a path relative to the root_space argument. For example, if root_space is tc.app and name_and_path is

"myplugin.MyEnum", it is equivalant to specifying root_space as tc.app.myplugin and name_and_path as "MyEnum".

Each call to ADD() will insert a new item into the enumeration set with arguments string name and zero or more number values. If the value arguments are omitted, a unique integer value will be generated automatically for the item (this is a sequence of natural numbers starting from 1). If more than one value is given, the numbers are 'mixed' together by addition. The value argument may also be a string referring to the name of an existing item, the value of that item will be used.

When done, the END_ENUM() method must be called to complete the definition. The reference to the enumeration function is released only at this point.

5.3. Specialised Types Bitwise Enumeration Syntax:

Bitwise enumerations are started with a call to tc.lang.Enum.defineBitwise. They differ in function from normal enumerations in only two aspects - the auto-generated numbers for the value arguments (if they are omitted on adding a new item) are bitwise distinct and mixing of values is done with a bitwise OR instead of addition.

Short-Hand Enumeration Syntax:

Items can also be added to an enumeration by directly appending them after the root_space and name_and_path arguments. Specifying a string alone will be taken

tc.lang.Enum.define [ Bitwise ] ( root_space, name_and_path [, name | name_value_pairs ]* )

[ .ADD( name [, value ]* ) ]*

.END_ENUM();

tc.lang.Enum.defineBitwise( root_space, name_and_path ) [ .ADD( name [, value ]* ) ]*

.END_ENUM();

(8)

as an item that requires an auto-generated value. Specifying an object with pairs of strings to number values will cause all the pairs to be added. Note that the short- hand syntax does not support mixing of values.

5.4. Instantiation

Enumerations can be instantiated after they have been defined to create items

(outside of the set) with custom values. To do this, apply JavaScript's new keyword

on the enumeration function (EG. new tc.app.myplugin.MyEnum("CustomItem",

123)). The new item created will behave exactly like any item in the original

enumeration set, except that it will not be available when iterating through the set

using foreach(fn, scope).

(9)

6. Keyword Reference

6.1. Headers/Footers

CONSTRUCTOR(fun)

Description: Specifies the constructor for a class (optional). If omitted, a default constructor is applied which directs all arguments to the super-class constructor (if available). If extending from another class,

this.Super(…) must be called in the constructor function to invoke the super-class constructor; not doing so will cause a runtime error on instantiation.

Parameters: fun – function to be called when the class is instantiated.

Annotations: DEPRECATED, TRACE, DEBUG Scope: non-static classes only.

END_CLASS()

Description: Terminates a class definition by registering and returning the class reference.

Parameters: - Annotations: -

Scope: classes only.

END_ENUM()

Description: Terminates an enum definition by registering and returning the enum reference.

Parameters: - Annotations: -

Scope: enumerations only

END_INTERFACE()

Description: Terminates an interface definition by registering and returning the interface reference.

Parameters: - Annotations: -

Scope: interfaces only.

EXTENDS(base), EXTENDS(ifaces ...)

Description: If applied in a class, specifies the base-class to extend from; can only be used before IMPLEMENTS. If applied in an interface, specifies the base-interfaces to extend from.

Parameters: base – reference to a non-static non-final class to extend, or a string. If a string, it must be a path to a non-static non-final class relative to the root given in tc.lang.Class.defineXXX(root, …).

ifaces – variable number of references to interfaces, or strings. If a

string, it must be a path to an interface relative to the root given in

tc.lang.Interface.define(root, …).

(10)

Annotations: -

Scope: non-static classes and interfaces.

IMPLEMENTS(ifaces ...)

Description: Specifies the interface(s) implemented by the class. Can only be used after EXTENDS.

Parameters: ifaces – variable number of references to interfaces, or strings. If a string, it must be a path to an interface relative to the root given in tc.lang.Class.defineXXX(root, …).

Annotations: -

Scope: non-static classes only.

6.2. Modifers

ABSTRACT()

Description: Marks a member or a member group as abstract – must be overriden. Cannot be used together with FINAL and STATIC, and cannot be applied on FIELDs.

Scope: abstract classes only.

FINAL()

Description: Marks a member or a member group as final – cannot be overriden.

Cannot be used together with ABSTRACT and STATIC.

Scope: classes only.

PRIVATE()

Description: Marks a member or a member group as private – can only be accessed within the scope of the construct. Note that private access is NOT enforced in the system, and is instead applied by appending

“__” (two underscores) to the name of every affected member.

Since the notion of ‘privateness’ is simply a naming convention, private methods can be overriden – but this is best avoided.

Scope: classes and static-members on interfaces.

PROTECTED()

Description: Marks a member or a member group as protected – can only be accessed within the scope of the namespace or in sub-classes. Note that protected access is NOT enforced in the system, and is instead applied by appending “_” (one underscore) to the name of every affected member.

Scope: classes and static-members on interfaces.

PUBLIC()

Description: Marks a member or a member group as public – no access

restriction. Note that all members are public by default and this is

provided simply for consistency.

(11)

Scope: classes and interfaces.

READONLY()

Description: Marks a member or a member group as read-only – cannot be modified. If applied on properties, the setter is not

generated/required. On other members, the read-only modifier is not enforced (it’s just an annotation).

Scope: classes and interfaces.

STATIC()

Description: Marks a member or a member group as static – the members reside on the construct itself. Cannot be used together with ABSTRACT and FINAL.

Scope: classes and interfaces.

WRITEONLY()

Description: Marks a member or a member group as write-only – cannot be read.

If applied on properties, the getter is not generated/required. On other members, the write-only modifier is not enforced (it’s just an annotation).

Scope: classes and interfaces.

6.3. Annotations

ANNOTE("@name", value), ANNOTE(annotation_subclass, arguments ...) Description: Applies a generic annotation on a member or a member group.

Annotations can be ad-hoc or customised.

An ad-hoc annotation is applied by specifying a string name prefixed with an ‘@’, followed by any value or object.

A customised annotation is applied by specifying a reference to a sub-class of tc.lang.Annotation (or a string path to the class, relative to the root) and providing the arguments passed to the class for instantiation.

Parameters: "@name" – identifier for the annotation, prefixed with an ‘@’.

value – any value or object for the annotation.

annotation_subclass – reference to an instantiatable class

extending tc.lang.Annotation, or a string. If a string, it must be a path to an instantiatable annotation class relative to the root given in tc.lang.Class.defineXXX(root, …).

arguments – list of arguments to be passed to the annotation_subclass for instantiation.

Scope: classes, interfaces and enumerations.

DEBUG(comment)

Description: Not a true annotation – it applies the effect of TRACE to all

members following its use. Once applied, it cannot be turned off in

the construct it is used in. This is useful for quickly putting a

(12)

class/interface into debug mode (to trace all methods) in order to locate a bug.

Parameters: comment – optional string comment to apply.

Scope: classes and interfaces.

DEPRECATED(comment, author)

Description: Annotates a member or a member group as deprecated. If used on methods or the constructor, the system will inform the user

whenever the function is invoked.

Parameters: comment – optional string comment to apply.

author – person responsible for the deprecation.

Scope: classes, interfaces and enumerations.

EVENT(comment)

Description: Annotates a member or a member group as an event. This is used to annotate methods as system event handlers, for the API to

recognise them.

Parameters: comment – optional string comment to apply.

Scope: classes and interfaces.

TRACE(comment)

Description: Annotates a member or a member group as traceable. When applied to methods or the constructor, the system tracks all invocations of the function (maintains a call stack). This information is obtainable by the programmer at runtime (on exceptions) and is extremely useful for debugging.

Parameters: comment – optional string comment to apply.

Scope: classes and interfaces.

TRANSIENT(comment)

Description: Annotates a member or a member group as transient. When applied to fields or properties, the system will not serialize them.

Parameters: comment – optional string comment to apply.

Scope: classes.

6.4. Members

ABSTRACT_CLASS(name), END_CLASS()

Description: Adds a nested abstract class. Equivalent to:

.CLASS(name, tc.lang.Class.TYPE_ABSTRACT)

The nested class is added as a static member of the outer construct, so the STATIC modifier is redundant. Must be terminated by an END_CLASS when done.

Parameters: name – name of nested abstract class.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, DEBUG

Scope: classes and interfaces.

(13)

ADD(name, values ...)

Description: Adds an item to an enumeration.

Parameters: name – item identifier.

values – zero or more integer values or strings (the names of existing items) from which the value will be copied. If bitwise, the values are ORed together, otherwise they are added up. If not specified, a unique value will be generated automatically.

Modifiers: -

Annotations: ANNOTE, DEPRECATED Scope: enumerations only.

BITWISE_ENUM(name), END_ENUM()

Description: Adds a nested bitwise enumeration. Equivalent to:

.ENUM(name, true)

The nested enum is added as a static member of the outer construct, so the STATIC modifier is redundant. Must be terminated by an END_ENUM when done.

Parameters: name – name of nested bitwise enumeration.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED

Scope: classes and interfaces.

CLASS(name, type), END_CLASS()

Description: Adds a nested class. The nested class is added as a static member of the outer construct, so the STATIC modifier is redundant. Must be terminated by an END_CLASS when done.

Parameters: name – name of nested abstract class.

type – optional constant denoting the type of class, either:

tc.lang.Class.TYPE_NORMAL, tc.lang.Class.TYPE_STATIC, tc.lang.Class.TYPE_ABSTRACT, tc.lang.Class.TYPE_FINAL Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE

Annotations: ANNOTE, DEPRECATED, DEBUG Scope: classes and interfaces.

CONSTANT(name, value)

Description: Adds a constant member. This is a shortcut for:

.READONLY().FINAL().FIELD(name, value)

Note that the read-only attribute is not enforced – annotation only.

Parameters: name – name of the constant.

value – any value or object, except for functions.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRANSIENT Scope: classes and interfaces.

ENUM(name, bitwise), END_ENUM()

Description: Adds a nested enumeration. The nested enum is added as a static

member of the outer construct, so the STATIC modifier is redundant.

(14)

Must be terminated by an END_ENUM when done.

Parameters: name – name of nested enumeration.

bitwise – optional boolean value for whether the enum should be bitwise or not.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED

Scope: classes and interfaces.

FIELD(name, value)

Description: Adds a field member.

Parameters: name – name of the field.

value – any value or object, except for functions.

Modifiers: STATIC, FINAL, PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY

Annotations: ANNOTE, DEPRECATED, TRANSIENT Scope: classes and static-members on interfaces.

FINAL_CLASS(name), END_CLASS()

Description: Adds a nested final class. Equivalent to:

.CLASS(name, tc.lang.Class.TYPE_FINAL)

The nested class is added as a static member of the outer construct, so the STATIC modifier is redundant. Must be terminated by an END_CLASS when done.

Parameters: name – name of nested final class.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, DEBUG

Scope: classes and interfaces.

GET(fun)

Description: Overrides or modifies the default getter created for a property. Note that if the access-level (private, protected, etc…) of the getter is modified, the overall access-level of the property will be recorded as the least restrictive access-level of both getter and setter.

Parameters: fun – function representing the overriden getter. The function will be invoked with the value stored in the property as the first argument, and should return a value of the same type (as the return value of the getter). If omitted, only the attributes of the default getter are modified.

Modifiers: ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRACE, DEBUG

Scope: classes and static-members on interfaces (only available immediately after PROPERTY).

INTERFACE(name), END_INTERFACE()

Description: Adds a nested interface. The nested interface is added as a static member of the outer construct, so the STATIC modifier is redundant.

Must be terminated by an END_INTERFACE when done.

Parameters: name – name of nested interface.

(15)

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, DEBUG

Scope: classes and interfaces.

METHOD(name, fun)

Description: Adds a method member.

Parameters: name – name of the method.

fun – function representing the method. If omitted, the method is considered to be ABSTRACT.

Modifiers: STATIC, ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRACE, EVENT, DEBUG

Scope: classes and interfaces.

PROPERTY(name, type, values ...), GET(), SET(), END_PROPERTY() Description: Adds a property member. The terminating END_PROPERTY is optional;

use if clarity is needed.

For classes or static-properties on interfaces:

A hidden super-private field will be created with the name

“___$Name” (3 under-scores and a ‘$’, followed by the name given with the first letter capitalised). By default, getter and setter methods will be created with the names “getName” and “setName”

respectively. If READONLY, only the getter will be created. If WRITEONLY, only the setter will be created.

Immediately after PROPERTY, GET and SET may be used to exercise fine-grained control over the getters and setters created.

For instance-properties on interfaces:

By default, getter and setter methods will be required (for implementation) with the names “getName” and “setName”

respectively. If READONLY, only the getter will be required. If WRITEONLY, only the setter will be required.

Parameters: name – name of the property.

type – string, instance of tc.lang.Type, or a reference to a construct, representing the type of the property. See “Property Type

Reference” for listings of the stock string types.

values – one or more values to be used as the initial value of the property. If omitted, the property will be given a default initial value depending on its type. Note that multiple values given will be merged into a single value – how the merging is done depends on the type.

Modifiers: STATIC, ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY

Annotations: ANNOTE, DEPRECATED, TRACE, TRANSIENT, DEBUG Scope: classes and interfaces.

SET(fun)

Description: Overrides or modifies the default setter created for a property. Note

that if the access-level (private, protected, etc…) of the setter is

(16)

modified, the overall access-level of the property will be recorded as the least restrictive access-level of both getter and setter.

Parameters: fun – function representing the overriden setter. The function will be invoked with the proposed new property value as the first argument, the old property value stored as the second argument, and should return a finalised value of the same type (to be stored). If the setter throws an exception, the system deems the set operation to have failed. If omitted, only the attributes of the default setter are modified.

Modifiers: ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRACE, DEBUG

Scope: classes and static-members on interfaces (only available immediately after PROPERTY).

THIS()

Description: Does not add anything; represents the current construct being defined. Allows annotations to be applied to the construct.

Parameters: - Modifiers: -

Annotations: ANNOTE, DEPRECATED

Scope: classes, interfaces and enumerations.

STATIC_CLASS(name), END_CLASS()

Description: Adds a nested static class. Equivalent to:

.CLASS(name, tc.lang.Class.TYPE_STATIC)

The nested class is added as a static member of the outer construct, so the STATIC modifier is redundant. Must be terminated by an END_CLASS when done.

Parameters: name – name of nested static class.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, DEBUG

Scope: classes and interfaces.

STATIC_CONSTANT(name, value)

Description: Adds a static constant member. This is a shortcut for:

.STATIC().CONSTANT(name, value) Parameters: name – name of the constant.

value – any value or object, except for functions.

Modifiers: PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED

Scope: classes and interfaces.

STATIC_FIELD(name, value)

Description: Adds a static field member. This is a shortcut for:

.STATIC().FIELD(name, value) Parameters: name – name of the field.

value – any value or object, except for functions.

Modifiers: PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY

(17)

Annotations: ANNOTE, DEPRECATED Scope: classes and interfaces.

STATIC_METHOD(name, fun)

Description: Adds a static method member. This is a shortcut for:

.STATIC().METHOD(name, fun) Parameters: name – name of the method.

fun – function representing the method.

Modifiers: PUBLIC, PROTECTED, PRIVATE

Annotations: ANNOTE, DEPRECATED, TRACE, EVENT, DEBUG Scope: classes and interfaces.

STATIC_PROPERTY(name, type, values ...), GET(), SET(), END_PROPERTY()

Description: Adds a static property member. The terminating END_PROPERTY is optional; use if clarity is needed. This is a shortcut for:

.STATIC().PROPERTY(name, type, values ...)

A hidden super-private field will be created with the name

“___$Name” (3 under-scores and a ‘$’, followed by the name given with the first letter capitalised). By default, getter and setter methods will be created with the names “getName” and “setName”

respectively. If READONLY, only the getter will be created. If WRITEONLY, only the setter will be created.

Immediately after PROPERTY, GET and SET may be used to exercise fine-grained control over the getters and setters created.

Parameters: name – name of the property.

type – string, instance of tc.lang.Type, or a reference to a construct, representing the type of the property. See “Property Type

Reference” for listings of the stock string types.

values – one or more values to be used as the initial value of the property. If omitted, the property will be given a default initial value depending on its type. Note that multiple values given will be merged into a single value – how the merging is done depends on the type.

Modifiers: PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY Annotations: ANNOTE, DEPRECATED, TRACE, DEBUG

Scope: classes and interfaces.

6.5. Others

GROUP(name), END_GROUP(name)

Description: Defines a member group for applying modifiers/annotations to members within them (or just simply for logical organisation).

Groups may be nested within one another; a nested group will

inherit the modifiers/annotations of the outer group – just like any

other member.

(18)

Parameters: name – optional group name. If specified, the system will verify that multiple GROUP and END_GROUP pairs are correctly nested and paired.

Modifiers: STATIC, ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE, READONLY, WRITEONLY

Annotations: ANNOTE, DEPRECATED, TRACE, TRANSIENT, EVENT, DEBUG Scope: classes and interfaces.

IMPORT_CONSTANT(source, name, newname)

Description: Imports a static constant from another construct, and adds it as a constant of the current one.

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

name – name of the static constant in the source to import.

newname – optional new name to be given to the imported constant. If omitted, the original name is used.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRANSIENT Scope: classes and interfaces.

IMPORT_CONSTANTS(source, pattern)

Description: Imports all static constants with names matching the regex pattern from another construct , and adds them as constants of the current one (retaining their original names).

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

pattern – regex that matches all the names of the desired static constants in the source.

Modifiers: STATIC, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRANSIENT Scope: classes and interfaces.

IMPORT_METHOD(source, name, newname)

Description: Imports a static method from another construct, and adds it as a method of the current one. The imported method retains its original scope (i.e. when executed, ‘this’ in the imported method refers to the original construct).

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

name – name of the static method in the source to import.

newname – optional new name to be given to the imported method. If omitted, the original name is used.

Modifiers: STATIC, ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRACE, EVENT, DEBUG

Scope: classes and static-members on interfaces.

(19)

IMPORT_METHODS(source, pattern)

Description: Imports all static methods with names matching the regex pattern from another construct , and adds them as methods of the current one (retaining their original names). The imported methods retain their original scope as well (i.e. when executed, ‘this’ in the imported methods refer to the original construct).

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

pattern – regex that matches all the names of the desired static methods in the source.

Modifiers: STATIC, ABSTRACT, FINAL, PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRACE, EVENT, DEBUG

Scope: classes and static-members on interfaces.

IMPORT_STATIC_CONSTANT(source, name, newname)

Description: Imports a static constant from another construct, and adds it as a static constant of the current one.

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

name – name of the static constant in the source to import.

newname – optional new name to be given to the imported constant. If omitted, the original name is used.

Modifiers: PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRANSIENT Scope: classes and interfaces.

IMPORT_STATIC_CONSTANTS(source, pattern)

Description: Imports all static constants with names matching the regex pattern from another construct , and adds them as a static constants of the current one (retaining their original names).

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

pattern – regex that matches all the names of the desired static constants in the source.

Modifiers: PUBLIC, PROTECTED, PRIVATE Annotations: ANNOTE, DEPRECATED, TRANSIENT Scope: classes and interfaces.

IMPORT_STATIC_METHOD(source, name, newname)

Description: Imports a static method from another construct, and adds it as a static method of the current one. The imported method retains its original scope (i.e. when executed, ‘this’ in the imported method refers to the original construct).

Parameters: source – reference to a construct to import from, or a string. If a

string, it must be a path to a construct relative to the root given in

tc.lang.XXX.defineYYY(root, …).

(20)

name – name of the static method in the source to import.

newname – optional new name to be given to the imported method. If omitted, the original name is used.

Modifiers: PUBLIC, PROTECTED, PRIVATE

Annotations: ANNOTE, DEPRECATED, TRACE, EVENT, DEBUG Scope: classes and interfaces.

IMPORT_STATIC_METHODS(source, pattern)

Description: Imports all static methods with names matching the regex pattern from another construct , and adds them as static methods of the current one (retaining their original names). The imported methods retain their original scope as well (i.e. when executed, ‘this’ in the imported methods refer to the original construct).

Parameters: source – reference to a construct to import from, or a string. If a string, it must be a path to a construct relative to the root given in tc.lang.XXX.defineYYY(root, …).

pattern – regex that matches all the names of the desired static methods in the source.

Modifiers: PUBLIC, PROTECTED, PRIVATE

Annotations: ANNOTE, DEPRECATED, TRACE, EVENT, DEBUG

Scope: classes and interfaces.

(21)

7. Stock Property Types Reference

This section lists all the stock property types provided. A type is specified as a string in the second argument to a PROPERTY member. Each type has a strict and relaxed mode (relaxed by default); where strict mode can be turned on by prepending ‘!’ to the type name when specifying it as a string. In general, strict mode implies that no attempt is made to convert values to the given type (when performing assignments) and null values are rejected for object types.

array

Relaxed Mode: If one value is given and it is an array or null, no conversion is done. Otherwise, a new array is created with all the values as elements.

Strict Mode: Only one value is accepted, and it must be an array (cannot be null).

Default Value: [] (empty array)

boolean

Relaxed Mode: Only one value is accepted, and it is converted to a boolean.

Strict Mode: Only one value is accepted, and it must already be a boolean.

Default Value: false

class

Relaxed Mode: Only one value is accepted, and it must be a reference to a class or null.

Strict Mode: Only one value is accepted, and it must be a reference to a class.

Default Value: null

construct

Relaxed Mode: Only one value is accepted, and it must be a reference to a construct or null.

Strict Mode: Only one value is accepted, and it must be a reference to a construct.

Default Value: null

date

Relaxed Mode: Only one value is accepted, and it must be a reference to a Date object, null, or a value convertible to a valid Date.

Strict Mode: Only one value is accepted, and it must be a reference to a Date object.

Default Value: null

(22)

enum

Relaxed Mode: Only one value is accepted, and it must be a reference to an enumeration or null.

Strict Mode: Only one value is accepted, and it must be a reference to an enumeration.

Default Value: null

function

Relaxed Mode: Only one value is accepted, and it must be a reference to a function or null.

Strict Mode: Only one value is accepted, and it must be a reference to a function.

Default Value: null

interface

Relaxed Mode: Only one value is accepted, and it must be a reference to an interface or null.

Strict Mode: Only one value is accepted, and it must be a reference to an interface.

Default Value: null

integer

Relaxed Mode: Values given are converted to numbers, added up, and converted to a single integer using Math.floor(). If the resulting value isNaN, the input is rejected.

Strict Mode: Only one value is accepted, and it must be an integer number.

Default Value: 0

jsobject

Relaxed Mode: Only one value is accepted, and it must be a generic JavaScript object (not from the class system) or null. (e.g. from JSON, Object, Array, Date, RegExp, etc…)

Strict Mode: Only one value is accepted, and it must be a generic JavaScript object (not from the class system).

Default Value: null

number

Relaxed Mode: Values given are converted to numbers and added up. If the resulting value isNaN, the input is rejected.

Strict Mode: Only one value is accepted, and it must be a number.

Default Value: 0

(23)

object

Relaxed Mode: Only one value is accepted, and it must be an object instantiated from a class system construct or null.

Strict Mode: Only one value is accepted, and it must be an object instantiated from a class system construct.

Default Value: null

regex

Relaxed Mode: Only one value is accepted, and it must be a reference to a RegExp object, null, or a value convertible to a valid RegExp.

Strict Mode: Only one value is accepted, and it must be a reference to a RegExp object.

Default Value: null

string

Relaxed Mode: Any value given is converted to string, multiple values are concatenated together to form a string.

Strict Mode: Only one value is accepted, and it must be a string.

Default Value: "" (empty string)

(24)

8. Reflection API Reference

Runtime reflection functions are accessible through the static class tc.lang.Reflect.

Listed below are the various static methods on the class.

foreachClass(obj, fn, scope)

Description:

Calls the given function for every class inherited by the object/construct.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the single argument (class_ref).

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachClass(tc.lang.test.Rectangle, function(c) { this.println("Class: " + c);

}, tc.io.stdout);

Parameters:

obj - Object whose inherited classes are to be iterated.

fn - Function to execute for each class.

scope - Value to use as the 'this' keyword when executing the function.

foreachField(obj, fn, scope, _all)

Description:

Calls the given function for every instance field on the object/construct.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the arguments (field_name, annotations, readable, writable, isFinal).

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the field can be read.

writable - boolean true if the field can be written to.

isFinal - boolean true if the field was declared final.

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachField(obj, function(name, ann, readable, writable, isFinal) {

this.println("Instance Field Name: " + name);

if (readable)

this.println(" Readable");

if (writable)

this.println(" Writable");

if (ann["@transient"]) this.println(" Transient");

}, tc.io.stdout);

Parameters:

obj - Object whose fields are to be iterated fn - Function to execute for each field.

Scope - Value to use as the 'this' keyword when executing the function.

_all - True to return all fields; false to return only public fields(default).

foreachInterface(obj, fn, scope)

Description:

Calls the given function for every interface implemented by the object/construct.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the single argument (interface_ref).

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachInterface(tc.lang.test.Swimmer, function(it) { this.println("Interface: " + it);

}, tc.io.stdout);

(25)

Parameters:

obj - Object whose implemented interfaces are to be iterated fn - Function to execute for each interface.

scope - Value to use as the 'this' keyword when executing the function.

foreachMethod(obj, fn, scope, _all)

Description:

Calls the given function for every instance method on the object/construct.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the arguments (method_name, annotations, isProperty, type, isFinal, isAbstract).

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

isProperty - boolean true if the method is a getter or setter or some property.

type - an instance of tc.lang.Type indicating the property type.

isFinal - boolean true if the method was declared final.

isAbstract - boolean true if the method was declared abstract.

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachMethod(obj, function(name, ann, isProp, type, isFinal, isAbstract) {

this.println("Instance Method Name: " + name);

if (ann["@deprecated"]) this.println(" Deprecated");

if (ann["@transient"]) this.println(" Transient");

}, tc.io.stdout);

Parameters:

obj - Object whose methods are to be iterated fn - Function to execute for each method.

scope - Value to use as the 'this' keyword when executing the function.

_all - True to return all methods; False to return only public methods (default).

foreachProperty(obj, fn, scope, _all)

Description:

Calls the given function for every instance property on the object/construct.

Only properties which are either publicly readable and/or writable will be listed.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the arguments (property_name, annotations, readable, writable, type, isFinal, isAbstract).

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the property has a getter.

writable - boolean true if the property has a setter.

type - an instance of tc.lang.Type indicating the property type.

isFinal - boolean true if the property was declared final.

isAbstract - boolean true if the property was declared abstract.

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachProperty(obj, function(name, ann, readable, writable, type, isFinal, isAbstract) {

this.println("Instance Property Name: " + name);

if (readable)

this.println(" Readable");

if (writable)

this.println(" Writable");

if (ann["@transient"]) this.println(" Transient");

}, tc.io.stdout);

Parameters:

obj - Object whose properties are to be iterated fn - Function to execute for each property.

scope - Value to use as the 'this' keyword when executing the function.

_all - True to return all properties; False to return only public properties (default).

foreachStaticField(obj, fn, scope, _all)

Description:

Calls the given function for every static field on the object/construct.

The function will be invoked with the 'scope' argument as the 'this' keyword

(26)

and with the arguments (field_name, annotations, readable, writable, isConstruct).

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the field can be read.

writable - boolean true if the field can be written to.

isConstruct - boolean true if the field is referring to a nested class/interface/enum.

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachStaticField(obj, function(name, ann, readable, writable, isConstruct) {

this.println("Static Field Name: " + name);

if (readable)

this.println(" Readable");

if (writable)

this.println(" Writable");

if (ann["@transient"]) this.println(" Transient");

}, tc.io.stdout);

Parameters:

obj - Object whose fields are to be iterated fn - Function to execute for each field.

scope - Value to use as the 'this' keyword when executing the function.

_all - True to return all fields; False to return only public fields (default).

foreachStaticMethod(obj, fn, scope, _all)

Description:

Calls the given function for every static method on the object/construct.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the arguments (method_name, annotations, isProperty, type).

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

isProperty - boolean true if the method is a getter or setter or some property.

type - an instance of tc.lang.Type indicating the property type.

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

tc.lang.Reflect.foreachStaticMethod(obj, function(name, ann, isProp, type) {

this.println("Static Method Name: " + name);

if (ann["@deprecated"]) this.println(" Deprecated");

if (ann["@transient"]) this.println(" Transient");

}, tc.io.stdout);

Parameters:

obj - Object whose methods are to be iterated fn - Function to execute for each method.

scope - Value to use as the 'this' keyword when executing the function.

_all - True to return all methods; False to return only public methods (default).

foreachStaticProperty(obj, fn, scope, _all)

Description:

Calls the given function for every static property on the object/construct.

Only properties which are either publicly readable and/or writable will be listed.

The function will be invoked with the 'scope' argument as the 'this' keyword and with the arguments (property_name, annotations, readable, writable, type).

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the property has a getter.

writable - boolean true if the property has a setter.

type - an instance of tc.lang.Type indicating the property type.

The iteration will stop if an exception is thrown or if the given function returns a non-false value. This non-false value will be the return value of the entire method.

Example:

(27)

tc.lang.Reflect.foreachStaticProperty(obj, function(name, ann, readable, writable, type) {

this.println("Static Property Name: " + name);

if (readable)

this.println(" Readable");

if (writable)

this.println(" Writable");

if (ann["@transient"]) this.println(" Transient");

}, tc.io.stdout);

Parameters:

obj - Object whose properties are to be iterated fn - Function to execute for each property.

scope - Value to use as the 'this' keyword when executing the function.

_all - True to return all properties; False to return only public properties (default).

getConstructInfo(obj)

Description:

Returns the meta-data of the given construct (includes the name, annotations, type, etc...). The return value will be a JSON object with the appropriate properties.

Parameters:

obj – reference to a construct.

getConstructName(obj)

Description:

Returns the name of the construct if the first argument is a class/interface/enum. Returns false otherwise.

Parameters:

obj – reference to a construct.

getField(obj, name)

Description:

Returns the meta-data for the specified public instance field on the object/construct. The return value will be an object with "annotations", "readable", "writable" and "isFinal" as properties.

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the field can be read.

writable - boolean true if the field can be written to.

isFinal - boolean true if the field was declared final.

Parameters:

obj - Object with the desired field name - Name of the instance field to obtain

getFields(obj, _all)

Description:

Returns all the instance fields on the object/construct.

The return value will be an object where all the property names are the field names and the corresponding value will be an object with "annotations", "readable", "writable" and "isFinal" as properties.

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the field can be read.

writable - boolean true if the field can be written to.

isFinal - boolean true if the field was declared final.

Example:

var fields = tc.lang.Reflect.getFields(obj);

for (var name in fields) {

tc.io.stdout.println("Instance Field Name: " + name);

if (fields[name].readable)

tc.io.stdout.println(" Readable");

if (fields[name].writable)

tc.io.stdout.println(" Writable");

if (fields[name].annotations["@transient"]) tc.io.stdout.println(" Transient");

}

Parameters:

obj - Object whose fields are to be obtained

_all - True to return all fields; False to return only public fields (default).

getMethod(obj, name)

Description:

Returns the meta-data for the specified instance method

on the object/construct. The return value will be an object with

(28)

"annotations", "isProperty", "type", "isFinal" and "isAbstract"

as properties.

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

isProperty - boolean true if the method is a getter or setter or some property.

type - an instance of tc.lang.Type indicating the property type.

isFinal - boolean true if the method was declared final.

isAbstract - boolean true if the method was declared abstract.

Parameters:

obj - Object with the desired method

name - Name of the instance method to obtain

getMethods(obj, _all)

Description:

Returns all the instance methods on the object/construct.

The return value will be an object where all the property names are the method names and the corresponding value will be an object with "annotations", "isProperty", "type", "isFinal" and "isAbstract"

as properties.

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

isProperty - boolean true if the method is a getter or setter or some property.

type - an instance of tc.lang.Type indicating the property type.

isFinal - boolean true if the method was declared final.

isAbstract - boolean true if the method was declared abstract.

Example:

var methods = tc.lang.Reflect.getMethods(obj);

for (var name in methods) {

tc.io.stdout.println("Instance Method Name: " + name);

if (methods[name].annotations["@deprecated"]) tc.io.stdout.println(" Deprecated");

if (methods[name].annotations["@transient"]) tc.io.stdout.println(" Transient");

}

Parameters:

obj - Object whose methods are to be obtained

_all - True to return all methods; False to return only public methods (default).

getProperties(obj, _all)

Description:

Returns all the instance properties on the object/construct.

Only properties which are either publicly readable and/or writable will be listed.

The return value will be an object with all the property names and the corresponding values will be objects with "annotations",

"readable", "writable", "type", "isFinal", and "isAbstract" as properties.

annotations - an object where each property name is the annotation ID and the corresponding value is an instance of tc.lang.Annotation.

readable - boolean true if the property has a getter.

writable - boolean true if the property has a setter.

type - an instance of tc.lang.Type indicating the property type.

isFinal - boolean true if the property was declared final.

isAbstract - boolean true if the property was declared abstract.

Example:

var props = tc.lang.Reflect.getProperties(obj);

for (var name in props) {

tc.io.stdout.println("Instance Property Name: " + name);

if (props[name].readable)

tc.io.stdout.println(" Readable");

if (props[name].writable)

tc.io.stdout.println(" Writable");

if (props[name].annotations["@transient"]) tc.io.stdout.println(" Transient");

}

Parameters:

obj - Object whose properties are to be obtained

_all - True to return all properties; False to return only public properties (default).

getProperty(obj, name)

Description:

Returns the meta-data for the specified public instance property on the object/construct. If the property is neither publicly readable nor writable, it will be as if the property did not exist.

References

Related documents