01 
02 /*
03  *  JScripter Standard 1.0 - To Script In Java
04  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
05  *  
06  *  This program is free software: you can redistribute it and/or modify
07  *  it under the terms of the GNU Affero General Public License as published by
08  *  the Free Software Foundation, either version 3 of the License, or
09  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU Affero General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU Affero General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 package js;
21 
22 import js.core.JsGlobal;
23 import js.core.JsObject;
24 
25 /**
26  * <p>An <b>opaque</b> class helping to simulate the JavaScript's late-evaluation feature 
27  * of object fields.</p>
28  * <p>This <b>opaque</b> class is especially helpful when used together with the <b>opaque</b> 
29  * class {@link Static} to make Java <tt>static final</tt> references to the fields of 
30  * JavaScript global objects which requires late-evaluation and refresh-on-reload in 
31  * JS applets or other JS Embed Simulations.</p>
32  *
33  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
34  * @see Static
35  * 
36  * @javascript <b>Opaque</b> types can be resolved but no class objects for them can be 
37  * generated into the target codes. Re-compilers must exit with error on the operations of 
38  * accessing that kind of class objects.
39  */
40 
41 public final class Field<T> extends Var<T>
42 {
43     private final Var<? extends JsObject> q;
44     private final Var.Member<?> m;
45 
46     /**
47      * <p>Creates a late-evaluation field with an opaque qualifier.</p>
48      * @param q The opaque qualifier for the field
49      * @param m The opaque member for the field
50      * @since 1.0
51      * @javascript Re-compilers must convert this constructor into the JavaScript expression: 
52      * <pre>q.m</pre>
53      * where <tt>m</tt> must be resolved to the field identifier at re-compile time.
54      */
55     public Field(Var<? extends JsObject> q, Var.Member<?> m) {
56         this.q = q;
57         this.m = m;
58     }
59 
60     /**
61      * <p>Creates a late-evaluation global field.</p>
62      * @param m The opaque member for the global field
63      * @since 1.0
64      * @javascript Re-compilers must convert this constructor into the JavaScript expression: 
65      * <pre>m</pre>
66      * where <tt>m</tt> m must be resolved to the field identifier at re-compile time.
67      */
68     public Field(Var.Member<?> m) {
69         this(global, m);
70     }
71 
72     private static final Var<JsGlobal> global = new Static<JsGlobal> (
73             new Var<JsGlobal>() {
74                 @Override
75                 public JsGlobal var() {
76                     return Js.core();
77                 }
78             }
79     );
80 
81     /**
82      * <p>Evaluates the field.</p>
83      * @since 1.0
84      * @javascript Re-compilers must ignore the virtual invocation of this method, that is, 
85      * replacing it with its current instance.
86      */
87     @SuppressWarnings("unchecked")
88     @Override
89     public T var() {
90         return (T)m.with(q.var());
91     }
92 }