ESOE Specification v0.1

来源:互联网 发布:宝宝学说话软件 编辑:程序博客网 时间:2024/04/30 03:34
 
ESOE Specification v0.1 (draft)
By Feng WeiGuo / forxm@21cn.com
2006-6
 
ESOE = ECMAScript OO Engine
Index
 
ESOE Specification v0.1 (draft)1
Index. 1
Definitions. 1
Levers. 2
Conventions. 2
Keywords. 2
Define ESOE Layout3
Create ESOE Engine. 4
Define Package. 4
Normalize Constructor/Function. 5
Normalize Non-ESOE Function. 5
Normalize Non-ESOE Object5
Define Class. 6
Derive from Base Class. 6
Define Class Layout7
Import Class. 7
Package Deployment (lv2)7
Set Package Path (lv2)8
Include Constructor (lv2)8
Include recursively (lv2)8
 
This specification defines a method of object-oriented programming with ECMAScript 3rd compatible language.
Definitions
Package: Objects to store name space structure.
Constructor: Function object
Class: Constructor.prototype
Declare: Let constructor create its class
Normalize: Load a constructor/object to a name space item
Import: Declare and Normalize.
Derive: Derive a class from a base class
Include: Load library file or class file.
Levers
 
Feature
Description
lever 1 (lv1)
1. Package definition
2. Class definition
3. Class deriving
4. Normalize non-esoe objects
1. Support script language compatible with ECMA-262 3rd
2. Manually load package.
3. An application's release version can use lv1 for efficiency.
lever 2 (lv2)
1. Automatically include package
 
1. Some script language may be unable to support this level.
Conventions
$esoe
ESOE engine it self
_property
Prefix "_" to a property, except the "$esoe.ns".
_keyword()
Prefix "_" to keyword function that has a global version (c2), keyword is in lowercase.
$esoe.keyword()
Keyword function that only in $esoe (c4) are lowercase.
$esoe.MyFunc()
To other function in $esoe, the first letter of each word is uppercase.
func
abbr. function/constructor
pkg
abbr. package
name
a String object
Keywords
Keywords conflicting
Type
Keywords
Description
c1
$esoe
prototype._esoe
[object]._esoe
If any c1 keywords conflict, ESOE engine will fail.
c2
_package / $esoe._package
_normalize / $esoe._normalize
_import / $esoe._import
_derive / $esoe._derive
_packagepath / $esoe._packagepath (lv2)
_update / $esoe._update (lv2)
If any c2 keywords conflict, close those keywords with the "nokey" parameter, and use the $esoe.* version.
So in the release version, it's better to convert all c2 keywords to their $esoe.* version.
c3
(prototype.)_base / (prototype.)_esoe._base
(prototype.)_pkg / (prototype.)_esoe._ pkg
c3 keywords are for normalizing non-esoe object. If any c3 keywords conflict with a non-esoe object, close this object's all c3 keywords when it's normalized, and use the _esoe.* version.
c4
$esoe.normalizeobject
[func]._declare / [func]._esoe._declare
c4 keywords will not conflict
Keywords description
Keyword
Description
$esoe
=GLOBAL.$esoe, the esoe engine itself
prototype._esoe / [object]._esoe
To maintain classes/objects
_package
Pre-define a package
_normalize
Load a constructor to a name space item
_import
Let constructor create it's class and map it to a name space
_derive
Derive a class from a base class
_packagepath (lv2)
Set the package path
_update (lv2)
If package loading need recursive process, call this to active it.
(prototype.)_base
Base class, that is, base class constructor's prototype
(prototype.)_pkg
The nearest package of a class
$esoe.normalizeobject
Normalize a non-esoe object
[func]._declare
Let constructor create it's class
Define ESOE Layout
ESOE layout include 3 parts,
1. Load ESOE engine, load parameters.
2. If any libraries are required, load them. It's optional for lv2.
3. If any libraries and classes are required, initialize all of them.
NOTE: ESOE layout is strongly required to be independent from other user codes, although it's not necessary in some environment.
 
Example for javasript in html page:
......
<script src="../esoe.js" level="2" debug="1"></script>              //load ESOE engine
<script src="../net/eae/webfx/xtree/xtree.js"></script>              //load libraries
<script>                                                                        //initialize packages and classes
_packagepath("com","../");
_import("net.eae.webfx.xtree.WebFXTree");
_import("net.eae.webfx.xtree.WebFXTreeItem");
_import("com.jsvm.js.lang.StringBuffer" , "myapp.StringBuffer");
_update ();
</script>                                                                       //ESOE layout end here
<script>......</script>                                                       //separated from other user code
......
<script>                                                                        //user code
       ......
       var obTree= new WebFXTree('name1');
       var sb= new myapp.StringBuffer;
       ......
</script >
Create ESOE Engine
Create a window.$esoe as an Object object.
 
It has below property that can be load from external.
_param
Save all of the parameter for later usage.
_path
ESOE engine path
_level
Level parameter, 1(default) or 2
_debug
Debug parameter, 0(default) or 1 in current version
_nokey
c2 keyword list to be forbidden
_libpath (lv2)
Default library path, only one path can be set. If not set, use _path as _libpath
_libmode (lv2)
0: do not automatically load library or class file (default).
1: load package library firstly, then class file.
2: load class file firstly, then package library.
3: load package library only
4: load class file only
 
It has below internal property,
ns
Name space map
_lib (lv2)
Name space map for library including
_lib.$count (lv2)
Set the number of files that included
Each of name space item of $esoe._lib has below property,
[item].$path (lv2)
Save package path set by _packagepath().
[item].$map (lv2)
Save the 2nd name space set by _import().
[item].$inc (lv2)
Set the number of times that a class/library has included.
[item].$fail (lv2)
Save the name space string if a class is not exist.
Define Package
In ESOE, a package is represented as name space chain. That is, a chain of objects under the $esoe.ns object, such as "com.mysite.myclass" is mapped to $esoe.ns.com.mysite.myclass. Every item in the chain is an Object object, or be other kind of object that can add property, such as a Function object, an Array object, etc. On the other side, Number object, String object, Boolean, undefined, null, etc., can not be a name space item, because they can not add any property.
Normalize Constructor/Function
Normalizing a constructor will firstly check that if the global name space had been prepared, else it will call _package() to create the package name space, and create a reference to the constructor. When create the reference, it’s important to check the name space confliction. If name space item has existed and it’s not the constructor itself, the normalizing process fail and return false. If $esoe._debug=1, it will alert an error message before return.
 
If the mapping success, it will add below property to the constructor’s prototype
prototype._esoe
An Object object to save the information for ESOE engine.
The prototype._esoe have below properties
_esoe._base
Record the constructor’s prototype of its base class.
_esoe._pkg
Record the nearest upper package namespace item of the class
_esoe._conflict
set to 1 if this class has any c3 keyword conflict
_esoe._nonesoe
set to 1 if this item is a non-esoe class/object
More, normalizing will do as below, like those system objects do in ECMAScript,
func.prototype.constructor= func
if _esoe._conflict=0, normalizing will do as below
func.prototype._base= func.prototype._esoe._base;
       func.prototype._pkg= func.prototype._esoe._pkg;
these two keywords are for the convenience for the users.
Normalize Non-ESOE Function
In ESOE, every Function object with its prototype prepared ( that is, the prototype will not be changed later) can be normalized. So just manually call _normalize() to load a non-esoe function to as a name space item. For an ESOE style class, ESOE will automatically do this work.
 
Normalizing a non-esoe function will not set the prototype.constructor and _esoe._base property.
Normalize Non-ESOE Object
For some existed library system, it may have used global variables. To rapidly transform these systems to be compatible with ESOE engine, global variables can be map into the name space also. It does just like normalizing a non-esoe function. The _esoe property is added to the object instead of prototype.
 
Normalizing non-esoe object is not including Number/String/Boolean/null, etc..
Define Class
In ESOE, class is represented as a constructor's prototype.
 
The constructor of every class should add a _declare property. The _declare property is a Function object with no argument. In the _declare function, the prototype can be created and/or initialized. The _declare() function is actually a callback function for the ESOE engine.
 
When user _import() a class, ESOE engine will call a constructor's _declare(), at this time, the constructor's prototype have not been a reference of any instance, for the [new constructor] statement has not been used to create the first instance of the class/constructor.
 
If the constructor has "_declare" keyword conflict, instead of creating _declare(), but create a _esoe._declare().ESOE engine will automatically select which to use.
 
For ESOE engine, defined a class as below,
1. Create a Function object. An empty prototype object is also created by ECMAScript engine.
2. If Function object do not have a "_declare" keyword conflict, add a _declare() property to the Function object. Otherwise, add a _esoe Object object as property of the Function object, then add a _declare() to the _esoe.
3. In the _declare(), created and/or initialized the prototype. The default prototype can be replaced in _declare().
 
If the _declare() need to import some class, try to import the class to a variable before deriving and normalizing, like below,
       var ns={};
       if( !_import("MyPkg.Class5","",ns) ) return false;
       …
       if( !_derive(…) ) return false;      
       …
       var a= new ns.Class5;
 
If the method of a class need to import another class, do it just like that in _declare(). But if the imported class is in the same package, it’s easier to do so,
       var a=new this._pkg.Class5;
Derive from Base Class
If a class is derived from a base class, let the prototype be an instance of its base class.
       [class].prototype= new [baseclass];
In the _declare() callback function, call _derive([thisclass],[baseclass]) instead of directly create the prototype.
 
For lv1, all base classes should have been included before deriving a class from them. Else the class will fail.
For lv2, if a base class is not imported, _derive() return false. When _derive() return false, the caller [func]._declare() should return false.
Define Class Layout
1. Prepare package namespace.
2. Create constructor and initializing process for the instance.
3. Create constructor’s _declare() process.
3.1 Import external classes
3.2 Call _normalize() for class without base class, or call _derive().
3.3 Add class property and method to the prototype of the class.
3.4 If _declare success, return true, else return false.
 
Example:
_package("MyPkg.sub");                                           // Prepare package namespace
$esoe.ns.MyPkg.sub.Class3= function(){}                        // Create constructor
$esoe.ns.MyPkg.sub.Class3._declare= function()                     // Create constructor’s _declare()
{
       var ns={};                                                               // Import external classes
       if( !_import("MyPkg.Class5","Class5",ns) ) return false;
      
       if( !_derive("MyPkg.sub.Class3","MyPkg.Class2") )       //derive or normalize
return false;
      
       with($esoe.ns.MyPkg.sub.Class3)                                  //add property to the prototype
       {
              prototype.p1= new ns.Class5;
              prototype.func1= function() {}
       }
       return true;                                                               //return
}
Import Class
Class Importing is like class normalizing, but the class is not mapped to $esoe.ns, it will map to a user appointed place. Also, the conflict checking is important.
Package Deployment (lv2)
For lv2, to deploy a package to a physical file path, just put the class file to the directory like that in name space chain, but replace the "." with "/", such as .../com/mysite/myclass.[file extension]. Especially, for ESOE lv2, if all classes of a package have packed together to a single file, name this file as .../com/mysite/_all.[file extension], then ESOE engine will also load this library file.
Set Package Path (lv2)
A package's path is saved to $esoe._lib.[item].$path. When retrieve the package name, the $path will append current package's name. ESOE engine will search the nearest package path if multiple package paths are set. For example,
if set
       _packagepath("com","../lib/" );
       _packagepath("com.mylib","../lib2/" );
then
       "com.xtree.WebFXTree" will be loaded from ../lib/com/xtree/WebFXTree
       "com.mylib.class1" will be loaded from ../lib2/ mylib/class1
Include Constructor (lv2)
If ESOE engine find that a constructor do not exist, it will set the corresponding [item].$fail and [item].$map of $esoe._lib. It will check [item].$inc of $esoe._lib and $esoe._libmode and the upper package's [item].$inc to see if it's needed to load the constructor. If it load the file, it will set [item].$inc and $esoe._lib.$count.
Include recursively (lv2)
If the including requires recursive process, call _update() at the last place to active the recursive mechanism.
原创粉丝点击