You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jt...@apache.org on 2017/11/29 05:05:54 UTC

[incubator-netbeans-html4j] 01/03: Allow self references when evaluating computed properties

This is an automated email from the ASF dual-hosted git repository.

jtulach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-netbeans-html4j.git

commit 6fc42674e0d46dba0545c19d839af4c9e1a5c51b
Author: Jaroslav Tulach <ja...@oracle.com>
AuthorDate: Tue Nov 28 07:51:17 2017 +0100

    Allow self references when evaluating computed properties
---
 .../netbeans/html/json/impl/ModelProcessor.java    |   8 +-
 .../java/org/netbeans/html/json/spi/Observers.java |   9 +-
 .../java/net/java/html/json/ComputedChainTest.java | 104 +++++++++++++++++++++
 3 files changed, 113 insertions(+), 8 deletions(-)

diff --git a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
index 3423c9a..2cce93e 100644
--- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
+++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java
@@ -272,7 +272,7 @@ public final class ModelProcessor extends AbstractProcessor {
                         boolean isPrimitive[] = {false};
                         String tn = checkType(p, isModel, isEnum, isPrimitive);
                         if (isModel[0]) {
-                            w.write("    prop_" + p.name() + " = this;\n");
+                            w.write("    prop_" + p.name() + " = TYPE; /* uninitialized */\n");
                         }
                     }
                 }
@@ -588,7 +588,7 @@ public final class ModelProcessor extends AbstractProcessor {
                 w.write("  }\n");
                 if (thisToNull) {
                     w.write("  private Object thisToNull(Object value) {\n");
-                    w.write("    return value == this ? null : value;\n");
+                    w.write("    return value == this || value == TYPE ? null : value;\n");
                     w.write("  }\n");
                 }
                 w.write("}\n");
@@ -671,7 +671,7 @@ public final class ModelProcessor extends AbstractProcessor {
                 w.write("  public " + tn + " " + gs[0] + "() {\n");
                 w.write("    proto.accessProperty(\"" + p.name() + "\");\n");
                 if (isModel[0]) {
-                    w.write("    if (prop_" + p.name() + " == this) prop_" + p.name() + " = new " + tn +"();\n");
+                    w.write("    if (prop_" + p.name() + " == TYPE) prop_" + p.name() + " = new " + tn +"();\n");
                 }
                 w.write("    return (" + tn + ")prop_" + p.name() + ";\n");
                 w.write("  }\n");
@@ -1780,7 +1780,7 @@ public final class ModelProcessor extends AbstractProcessor {
                     w.write("    ret.prop_" + p.name() + " = " + gs[0] + "();\n");
                     continue;
                 }
-                w.write("    ret.prop_" + p.name() + " =  prop_" + p.name() + " == null ? null : prop_" + p.name() + " == this ? ret : " + gs[0] + "().clone();\n");
+                w.write("    ret.prop_" + p.name() + " =  prop_" + p.name() + " == null ? null : prop_" + p.name() + " == TYPE ? TYPE : " + gs[0] + "().clone();\n");
             } else {
                 w.write("    proto.cloneList(ret." + gs[0] + "(), ctx, prop_" + p.name() + ");\n");
             }
diff --git a/json/src/main/java/org/netbeans/html/json/spi/Observers.java b/json/src/main/java/org/netbeans/html/json/spi/Observers.java
index 19f6b16..622f8dc 100644
--- a/json/src/main/java/org/netbeans/html/json/spi/Observers.java
+++ b/json/src/main/java/org/netbeans/html/json/spi/Observers.java
@@ -20,6 +20,7 @@ package org.netbeans.html.json.spi;
 
 import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 import org.netbeans.html.json.impl.SimpleList;
 
 /**
@@ -37,7 +38,6 @@ final class Observers {
     
     static Usages beginComputing(Proto p, String name, Usages usages) {
         synchronized (GLOBAL) {
-            verifyUnlocked(p);
             final Watcher nw = new Watcher(p, name);
             GLOBAL.add(nw);
             return Usages.register(name, nw, usages);
@@ -68,9 +68,9 @@ final class Observers {
     static void finishComputing(Proto p) {
         synchronized (GLOBAL) {
             boolean found = false;
-            Iterator<Watcher> it = GLOBAL.iterator();
-            while (it.hasNext()) {
-                Watcher w = it.next();
+            ListIterator<Watcher> it = GLOBAL.listIterator(GLOBAL.size());
+            while (it.hasPrevious()) {
+                Watcher w = it.previous();
                 if (w.proto == p && w.owner == Thread.currentThread()) {
                     if (w.prop != null) {
                         Observers mine = p.observers(true);
@@ -78,6 +78,7 @@ final class Observers {
                     }
                     found = true;
                     it.remove();
+                    break;
                 }
             }
             if (!found) {
diff --git a/json/src/test/java/net/java/html/json/ComputedChainTest.java b/json/src/test/java/net/java/html/json/ComputedChainTest.java
new file mode 100644
index 0000000..8f0f842
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/ComputedChainTest.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package net.java.html.json;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+
+@Model(className = "Chain", builder = "put", properties = {
+    @Property(name = "value", type = int.class),
+    @Property(name = "next1", type = Chain.class),
+    @Property(name = "next2", type = Chain.class),
+    @Property(name = "next3", type = Chain.class),
+    @Property(name = "next4", type = Chain.class),
+})
+public class ComputedChainTest {
+    @ComputedProperty
+    static int value1234(int value, Chain next1) {
+        return value + next1.getValue234();
+    }
+
+    @ComputedProperty
+    static int value234(int value, Chain next2) {
+        return value + next2.getValue34();
+    }
+
+    @ComputedProperty
+    static int value34(int value, Chain next3) {
+        return value + next3.getValue4();
+    }
+
+    @ComputedProperty
+    static int value4(int value, Chain next4) {
+        return value + next4.getValue();
+    }
+
+    @Test
+    public void chainOfValues() {
+        Chain root = new Chain();
+        Chain n1 = new Chain();
+        Chain n2 = new Chain();
+        Chain n3 = new Chain();
+        Chain n4 = new Chain();
+
+        root.setNext1(n1);
+        n1.setNext2(n2);
+        n2.setNext3(n3);
+        n3.setNext4(n4);
+
+        root.setValue(3);
+        n1.setValue(4);
+        n2.setValue(5);
+        n3.setValue(6);
+        n4.setValue(10);
+
+        assertEquals(root.getValue1234(), 28);
+    }
+
+    @Test
+    public void cyclicChain() {
+        Chain root = new Chain();
+        root.setValue(11);
+        Chain next = new Chain();
+        next.setValue(7);
+
+        root.setNext1(next);
+        next.setNext2(root);
+        root.setNext3(next);
+        next.setNext4(root);
+
+        assertEquals(root.getValue1234(), 47);
+    }
+
+    @Test
+    public void selfChain() {
+        Chain root = new Chain();
+        root.setValue(6);
+
+        root.setNext1(root);
+        root.setNext2(root);
+        root.setNext3(root);
+        root.setNext4(root);
+
+        assertEquals(root.getValue1234(), 30);
+    }
+
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@netbeans.apache.org" <co...@netbeans.apache.org>.