Revision: 4532
          http://sourceforge.net/p/vexi/code/4532
Author:   mkpg2
Date:     2013-06-20 17:03:57 +0000 (Thu, 20 Jun 2013)
Log Message:
-----------
Change. Make $vars accessible from child/sibling scopes.
- More convenient when setting up action listeners for buttons for example. 
- The 'down side' is that outer ids will be null when inner templates are being 
instantiated.
Fix. Line numbering when using sub templates.

Modified Paths:
--------------
    branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VML.java
    
branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java
    branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/TestGUT.java
    branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate.t
    
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java

Added Paths:
-----------
    
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate2.t
    
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate_ids.t

Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VML.java
===================================================================
--- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VML.java      
2013-06-01 18:35:31 UTC (rev 4531)
+++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VML.java      
2013-06-20 17:03:57 UTC (rev 4532)
@@ -2,7 +2,10 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.ibex.js.Backtraceable;
 import org.ibex.js.JS;
@@ -11,21 +14,26 @@
 import org.ibex.js.parse.Function;
 import org.ibex.util.Tree;
 import org.vexi.core.VML.Static.Template;
+import org.vexi.core.VML.Static.Template.PerInstantiationScope;
 
 public class VML implements Constants {
 
     static public class SubBlessing extends JS.Obj {
+       final PerInstantiationScope idContextParent; 
        final JS property;
         final Template template;
-        SubBlessing(String property, Template template){
-               this.property = JSU.S(property);
+        SubBlessing(PerInstantiationScope idContextParent, JS property, 
Template template){
+               this.idContextParent = idContextParent;
+               this.property = property;
                this.template = template;
         }
         @Override public JS new_(JS[] args) throws JSExn {
                return apply(null,args);
         }        
        @Override public JS apply(JS this_, JS[] args) throws JSExn {
-               return template.apply(this_,args);
+               JS[] thisHolder = new JS[]{this_}; 
+               template.apply(thisHolder,args, idContextParent, null);
+               return thisHolder[0];
        }       
        @Override public String coerceToString() {
                return "SubString$"+Integer.toHexString(hashCode());
@@ -40,7 +48,9 @@
         Template template;
         
         public Static(JS vexi, JS constructor, String sourceName) {
-            super(null);
+               // UGLY in fact it doesn't matter what the elementStart, it is 
only 
+               // used for skipping lines, but we are never inside another 
code block.
+            super(null, -1);  
             this.vexi = vexi;
             this.constructor = constructor;
             this.sourceName = sourceName;
@@ -111,7 +121,7 @@
             Object script = null;              ///< the script on this node
 
             List children = null;              ///< during XML parsing, this 
holds the list of currently-parsed children; null otherwise
-            List subtemplates = null;          ///< sub templates to be 
assigned to properties, not applied on creation
+            Map subtemplates = null;          ///< sub templates to be 
assigned to properties, not applied on creation
             Object preapply = null;            ///< Pre-applied template 
(~linked list) in root node only (unless lang:apply)
             Object principal = null;           ///< Template to be applied
             
@@ -130,10 +140,9 @@
 
             // Static data/methods 
///////////////////////////////////////////////////////////////////
             // FOOTNOTE:1
-            Template(CodeBlock parent, Template preapply, int startLine) {
-                super(parent);
+            Template(CodeBlock parent, int elementStart, Template preapply) {
+                super(parent, elementStart);
                 this.preapply = preapply;
-                this.startLine = startLine;
             }
             
                        void addChild(Template template) {
@@ -142,8 +151,8 @@
                        }
                        
                        void addSubTemplate(String property, Template template) 
{
-                               if(subtemplates==null) subtemplates = new 
ArrayList(); 
-                               subtemplates.add(new SubBlessing(property, 
template));
+                               if(subtemplates==null) subtemplates = new 
LinkedHashMap(); 
+                               subtemplates.put(JSU.S(property), template);
                        }
                        
             // Methods to apply templates 
////////////////////////////////////////////////////////
@@ -157,7 +166,7 @@
             // @param ptemplates a vector of the fileNames to recieve private 
references on the pboxes
             public JS apply(JS this_, JS[] args) throws JSExn {
                 JS[] thisHolder = new JS[] { this_ };
-                apply(thisHolder, args, null);
+                apply(thisHolder, args, null, null);
                 return thisHolder[0];
             }
 
@@ -182,12 +191,12 @@
                         t = 
((Blessing)Vexi.resolveString(vexi,t.getStatic().sourceName)).getTemplate();
                     }
                 }
-                t.apply(thisHolder, args, null);
+                t.apply(thisHolder, args, null, null);
                 return (Template)t;
             }
             
             
-            private void apply(JS[] thisHolder, JS[] args, 
PerInstantiationScope parentPis) throws JSExn {
+            void apply(JS[] thisHolder, JS[] args, PerInstantiationScope 
idContextParent, PerInstantiationScope idContext) throws JSExn {
                 Main.SCHEDULER.findCurrentInterpreter().enterNonJSCall(this);
                 try {
                     // REMARK - the preapplies may not have been resolved yet, 
@@ -208,24 +217,28 @@
                     }
                     
                     // FIXME this dollar stuff is all wrong
-                    if (id!=null && parentPis!=null) {
-                        parentPis.putDollar(id, this_);
-                    }
+                    
 
                     // FEATURE only if necessary (i.e. if there is JS code)
-                    PerInstantiationScope pis = new 
PerInstantiationScope(this_, parentPis, isBox());
-                        
+                    PerInstantiationScope pis = new 
PerInstantiationScope(idContextParent, idContext, this_, isBox());
+                    pis.idContext.putDollar(id, this_);
+                    
                     // FIXME needs to obey the new application-ordering rules
                     for (int i=0; children!=null && i<children.size(); i++) {
                         JS[] kidHolder = new JS[1];
-                        ((Template)children.get(i)).apply(kidHolder, null, 
pis);
+                        ((Template)children.get(i)).apply(kidHolder, null, 
idContextParent, pis.idContext);
                         JS ind = 
Main.SCHEDULER.getAndTriggerTraps(this_,SC_numchildren);
                         Main.SCHEDULER.putAndTriggerTraps(this_, ind, 
kidHolder[0]);
                     }
                     
-                    for (int i=0; subtemplates!=null && i<subtemplates.size(); 
i++) {
-                        SubBlessing subTemplate = 
(SubBlessing)subtemplates.get(i);
-                        Main.SCHEDULER.putAndTriggerTraps(this_, 
subTemplate.property, subTemplate);
+                    if(subtemplates!=null){
+                       Iterator I = subtemplates.keySet().iterator();
+                       while(I.hasNext()){
+                               JS property = (JS)I.next();
+                               Template subTemplate = 
(Template)subtemplates.get(property);
+                               SubBlessing subBlessing = new SubBlessing(pis, 
property, subTemplate);
+                               Main.SCHEDULER.putAndTriggerTraps(this_, 
property, subBlessing);                
+                       }                       
                     }
 
                     if (keys!=null) {
@@ -267,7 +280,7 @@
 
                     if (script==null) {
                         //pisParserParam = 
TemplateBuilder.instance.createPIChecker(uriPrefixes, this);
-                        script = VMLBuilder.parseScript(content, 
content_start, sourceName);
+                        script = VMLBuilder.parseScript(content, contentStart, 
sourceName);
                         content = null;
                         // FIXME: UGLY - avoiding adding an init param
                         if (script==null) {
@@ -277,17 +290,13 @@
                     if (script!=JSU.F) {
                         JSU.cloneWithNewGlobalScope((Function)script, 
pis).apply(null, args!=null?args:EMPTY_JS_ARRAY);
                     }
-
-                    // FIXME: nix this
-                    pis.parentBoxPis = null;
-                    
                 } finally {
                     Main.SCHEDULER.findCurrentInterpreter().exitNonJSCall();
                 }
             }
 
             public String traceLine() {
-                return sourceName +":" +startLine + "(apply)";
+                return sourceName +":" +elementStart + "(apply)";
             }
             
             /** 
@@ -310,39 +319,57 @@
              * $x for child boxes + uri prefix objects + global + static object
              * </p>
              */
-            class PerInstantiationScope extends JS.Obj {
-                PerInstantiationScope parentBoxPis;
-                final JS box;
+            class PerInstantiationScope extends JS.Immutable {
+               final PerInstantiationScope idContextParent;
+                final PerInstantiationScope idContext;
+                final JS object;
                 final boolean jsObj;
                 private JS subComponents;
+                
+                public PerInstantiationScope(PerInstantiationScope 
idContextParent, PerInstantiationScope idContext, JS object, boolean isBox) {
+                    this.idContextParent = idContextParent;
+                    this.idContext = idContext==null?this:idContext;
+                    this.object = object;
+                    this.jsObj = !isBox;
+                }
+                
+                
                 void putDollar(String key, JS target) throws JSExn {
-                    if (parentBoxPis!=null) {
-                        parentBoxPis.putDollar(key, target);
-                    }
                     JS jskey = JSU.S("$" + key);
-                    sput(jskey, target);
+                    idContext.putDollar(jskey, target);
                 }
                 // JS:FIXME: ugly
-                void sput(JS key, JS val) throws JSExn { 
+                private void putDollar(JS key, JS val) throws JSExn { 
                     if (subComponents==null) { 
                         subComponents = new JS.Obj();
-                        box.put(SC_subComponents, subComponents);
+                        object.put(SC_subComponents, subComponents);
                     }
                     subComponents.put(key,val); 
                 }
-                public PerInstantiationScope(JS box, PerInstantiationScope 
parentBoxPis, boolean isBox) {
-                    this.parentBoxPis = parentBoxPis;
-                    this.box = box;
-                    this.jsObj = !isBox;
+                
+                public JS getDollar(JS key) throws JSExn{
+                    if (subComponents!=null){
+                       JS r = subComponents.get(key);
+                       if(r!=null) return r;
+                    }
+                    if(idContextParent!=null){
+                       return idContextParent.getDollar(key);
+                    }
+                    return null;
                 }
+                
+
                 public JS get(JS key) throws JSExn {
                     JS r;
                     if (JSU.isString(key)) {
+                       String s = JSU.toString(key);
                         // FIXME This is a hack
                         //  1.returns $x for named child boxes
-                        if (subComponents!=null && 
subComponents.get(key)!=null) {
-                            return subComponents.get(key);
-                        }
+                       if(s.startsWith("$")){
+                               return idContext.getDollar(key);
+
+                       }
+                        
                         // FEATURE store null placeholder here if uri prefix 
doesn't
                         // exist and cache values using super.put to save one 
hash lookup
                         //  2.return prefix
@@ -355,34 +382,33 @@
                             return r;
                         }
                         // HACK. Use 'this' keyword instead?
-                        String s = JSU.toString(key);
                         if (jsObj && "thisobj".equals(s)) {
-                            return box;
+                            return object;
                         }
                     }
                     // FIXME: This won't work with traps that do blocking 
operations
-                    return Main.SCHEDULER.getAndTriggerTraps(box,key);
+                    return Main.SCHEDULER.getAndTriggerTraps(object,key);
                 }
 
                 // FIXME should come from JSGlobalScope ... or something 
                 public void put(JS key, JS val) throws JSExn {
-                    Main.SCHEDULER.putAndTriggerTraps(box,key,val);
+                    Main.SCHEDULER.putAndTriggerTraps(object,key,val);
                 }
                 
                 public JS callMethod(JS this_, JS method, JS[] args) throws 
JSExn {
-                    return box.callMethod(box, method, args);
+                    return object.callMethod(object, method, args);
                 }
                 
                 // FIXME this should come from JSGlobalScope or something
-                public void addTrap(JS key, JS f) throws JSExn { 
box.addTrap(key,f); }
-                public void delTrap(JS key, JS f) throws JSExn { 
box.delTrap(key,f); }
-                public Trap getTrap(JS key) { return box.getTrap(key); }
+                public void addTrap(JS key, JS f) throws JSExn { 
object.addTrap(key,f); }
+                public void delTrap(JS key, JS f) throws JSExn { 
object.delTrap(key,f); }
+                public Trap getTrap(JS key) { return object.getTrap(key); }
                 public String toString() { return "PIS of " + 
Template.this.toString(); }
                 
             }
             
             public String toString() {
-                return sourceName +":"+ startLine;
+                return sourceName +":"+ elementStart;
             }
         }
     }
@@ -391,8 +417,8 @@
        final boolean apply;
         Template template;            
 
-        public SubTemplate(CodeBlock parent, boolean apply) {
-               super(parent);
+        public SubTemplate(CodeBlock parent, int elementStart, boolean apply) {
+               super(parent, elementStart);
                this.apply = apply;
                }
     }
@@ -403,14 +429,15 @@
         
         // Only used during parsing 
/////////////////////////////////////////////////////////////////
         StringBuffer content = null;   ///< during XML parsing, this holds 
partially-read character data; null otherwise
-        int content_start = 0;         ///< line number of the first line of 
<tt>content</tt>
-        int startLine = -1;            ///< the line number that this element 
starts on
+        int contentStart = -1;         ///< line number of the first line of 
<tt>content</tt>
+        int elementStart = -1;         ///< the line number that this element 
starts on
         
         Prefixes uriPrefixes;          /// Uri prefixes->Blessings
         
        
-        CodeBlock(CodeBlock parent) {
+        CodeBlock(CodeBlock parent, int elementStart) {
             this.parent = parent;
+            this.elementStart = elementStart;
         }
         
         /**

Modified: 
branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java
===================================================================
--- 
branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java   
    2013-06-01 18:35:31 UTC (rev 4531)
+++ 
branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java   
    2013-06-20 17:03:57 UTC (rev 4532)
@@ -214,7 +214,7 @@
                     if (Log.user.isDebug()) {
                         Log.debug(Helper.class, "Parsing template: " + 
sourceName());
                     }
-                    Function staticScript = parseScript(static_.content, 
static_.content_start, sourceName());
+                    Function staticScript = parseScript(static_.content, 
static_.contentStart, sourceName());
                     if (t != null) {
                         static_.template = t;
                         
Main.SCHEDULER.findCurrentInterpreter().enterNonJSCall( static_);
@@ -332,28 +332,28 @@
             case STATE_IN_ROOT_NODE:
             case STATE_IN_APPLY_NODE:
             case STATE_IN_SUB_TEMPLATE_NODE:
-                CodeBlock parent = state!=STATE_IN_ROOT_NODE?cb.parent:null;
+               CodeBlock parent = state!=STATE_IN_ROOT_NODE?cb.parent:null;
                 Template preapply = t;
-                cb = t = static_.new Template(parent, preapply, getLine());
+                cb = t = static_.new Template(parent, getLine(), preapply);
                 state = STATE_IN_TEMPLATE_NODE;
                 break;
             case STATE_IN_TEMPLATE_NODE:
                 if (langUri){
                     if("apply".equals(cur.getLocalName())) {
-                        cb = new SubTemplate(t, true);
+                        cb = new SubTemplate(t, getLine(), true);
                         t = null;
                         state = STATE_IN_APPLY_NODE;
                         cb.uriPrefixes = prefixes;
                         return;
                     }else if("subtemplate".equals(cur.getLocalName())){
-                        cb = new SubTemplate(t, false);
+                        cb = new SubTemplate(t, getLine(), false);
                         t = null;
                         state = STATE_IN_SUB_TEMPLATE_NODE;
                         cb.uriPrefixes = prefixes;
                         return;
                     }
                 }
-                cb = t = static_.new Template(t, null, getLine());
+                cb = t = static_.new Template(t, getLine(), null);
                 break;
             }
             // JS Code has access to namespace objects
@@ -469,7 +469,8 @@
             cb = (CodeBlock) nodeStack.lastElement();
             nodeStack.setSize(nodeStack.size() - 1);
             if (cb.content != null) {
-                insertNewLines(cb.content, getLine() - oldCb.startLine);
+               int lines = getLine() - oldCb.elementStart;
+                insertNewLines(cb.content, lines);
             }
             // UGLY ...
             
@@ -510,7 +511,7 @@
                 return;
             default:
                 if (cb.content == null) {
-                    cb.content_start = getLine();
+                    cb.contentStart = getLine();
                     cb.content = new StringBuffer();
                 }
                 cb.content.append(ch, start, length);
@@ -540,7 +541,7 @@
             case STATE_IN_ROOT_NODE:
             case STATE_IN_TEMPLATE_NODE:
                 if (cb.content == null) {
-                    cb.content_start = getLine();
+                    cb.contentStart = getLine();
                     cb.content = new StringBuffer();
                 }
                 StringBuffer sb = cb.content;

Modified: 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/TestGUT.java
===================================================================
--- branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/TestGUT.java  
2013-06-01 18:35:31 UTC (rev 4531)
+++ branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/TestGUT.java  
2013-06-20 17:03:57 UTC (rev 4532)
@@ -15,7 +15,7 @@
     
     public static void main(String[] args) throws Throwable {
        CoreTestSuite cts = new CoreTestSuite(TestGUT.class);
-       TestCase t = cts.createTestCase(cts.getResourceDirs(), 
"dontvirtualize.t");
+       TestCase t = cts.createTestCase(cts.getResourceDirs(), 
"evaltemplate2.t");
        t.runBare();
        }
 }

Modified: 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate.t
===================================================================
--- 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate.t    
    2013-06-01 18:35:31 UTC (rev 4531)
+++ 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate.t    
    2013-06-20 17:03:57 UTC (rev 4532)
@@ -9,8 +9,8 @@
               "&lt;ui:box x=\"1\"/>"+
               "&lt;/vexi>");
         .util..assertEquals("I'm alive!",.x..f());
-        var x = .x(vexi.box);
-        .util..assertEquals(1,x.x);
+        .util..assertEquals(1,.x(vexi.box).x);
+        .util..assertEquals(1,new .x().x);
     };
     
        

Added: 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate2.t
===================================================================
--- 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate2.t   
                            (rev 0)
+++ 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/gut/evaltemplate2.t   
    2013-06-20 17:03:57 UTC (rev 4532)
@@ -0,0 +1,25 @@
+<vexi xmlns:ui="vexi://ui" xmlns="">
+
+    const TEMPLATE =  """
+            &lt;vexi xmlns:ui=\"vexi://ui\">
+                static.f=function(){return \"I'm alive!\";}
+                &lt;ui:box x=\"1\"/>
+            &lt;/vexi>
+            """;
+    
+    vexi.thread = function(){
+        var templateStream = vexi.stream.fromString(TEMPLATE);
+        var template = vexi.bless(templateStream);
+        
+        trace(template..f());
+        .util..assertEquals("I'm alive!",template..f());
+        
+        var anInstance = new template();    
+        trace(anInstance.x);
+        .util..assertEquals(1,anInstance.x);
+    };
+    
+       
+    
+    <ui:box/>
+</vexi>

Modified: 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java
===================================================================
--- 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java
        2013-06-01 18:35:31 UTC (rev 4531)
+++ 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java
        2013-06-20 17:03:57 UTC (rev 4532)
@@ -17,7 +17,7 @@
 
        CoreTestSuite cts = new CoreTestSuite(TestTemplate.class);
 //     TestCase t = cts.createTestCase(cts.getResourceDirs(), "lang_apply.t");
-       TestCase t = cts.createTestCase(cts.getResourceDirs(), 
"lang_subtemplate.t");
+       TestCase t = cts.createTestCase(cts.getResourceDirs(), 
"lang_subtemplate_ids.t");
        t.runBare();
        }
 }

Added: 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate_ids.t
===================================================================
--- 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate_ids.t
                           (rev 0)
+++ 
branches/vexi3/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate_ids.t
   2013-06-20 17:03:57 UTC (rev 4532)
@@ -0,0 +1,37 @@
+<vexi xmlns:ui="vexi://ui" xmlns:lang="vexi://lang">
+    <ui:Box id="outer" text="Outer" redirect=":$content">
+        <ui:Box id="title" text="Ids Test"/>
+        <ui:Box id="main" text="Moo">
+            thisbox.path ++= function(){
+                return $outer.text+" / "+$title.text+" / "+text;
+            };
+        </ui:Box>
+        
+        
+        <ui:Box id="content"/>
+    
+
+    
+        <lang:subtemplate property="sub">
+            <ui:Box>
+                <ui:Box id="item"/>
+                $item.text = arguments[0];
+                
+                thisbox.path ++= function(){
+                    return $outer.text+" / "+$title.text +" / "+$item.text;
+                };
+                    
+            </ui:Box>
+        </lang:subtemplate>
+        .util..assertEquals(0,thisbox.numchildren);
+        
+        thisbox.add(new sub("A"));
+        thisbox.add(new sub("B"));
+        
+        .util..assertEquals("Outer / Ids Test / Moo",$main.path);
+        .util..assertEquals("Outer / Ids Test / A",thisbox[0].path);
+        .util..assertEquals("Outer / Ids Test / B",thisbox[1].path);
+
+    </ui:Box>
+    
+</vexi>

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to