flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mschma...@apache.org
Subject [1/2] git commit: [flex-falcon] [refs/heads/develop] - Package level testing of fields and method access using chrom.js - It seems the injected static vars and instance vars in namespace classes are neccessary since the classes actually hold fields a
Date Sat, 13 Jun 2015 20:10:36 GMT
Repository: flex-falcon
Updated Branches:
  refs/heads/develop 00db22b88 -> 88d0b23aa


Package level testing of fields and method access using chrom.js
- It seems the injected static vars and instance vars in namespace
  classes are neccessary since the classes actually hold fields
  and methods.
- I can type 'chrome.app.isInstalled' and 'chrome.webstore.install()'
  from the IDE like the google docs show when talking about how to use
  the chrome packages.
- Where 'chrome' is a class, 'app' is a class inside the directory 'chrome'
  and is also a static var 'app' in the class 'chrome' and isInstalled is an
  instance field.
- Same applies to 'webstore', install() is an instance method in the class
  'webstore' located in the 'chrome' package. 'webstore' is also a static
  var in the 'chrome' class for dot notation access that is expected in JS.


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/5b48d61b
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/5b48d61b
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/5b48d61b

Branch: refs/heads/develop
Commit: 5b48d61b2b63f91d31e51a44d1f4e2dbfcfe9421
Parents: 00db22b
Author: Michael Schmalle <mschmalle@apache.org>
Authored: Sat Jun 13 16:07:52 2015 -0400
Committer: Michael Schmalle <mschmalle@apache.org>
Committed: Sat Jun 13 16:07:52 2015 -0400

----------------------------------------------------------------------
 .../codegen/externals/TestExternChrome.java     | 104 +++++++++++-
 .../codegen/externals/pass/AddMemberPass.java   | 165 ++++++-------------
 .../externals/reference/ClassReference.java     |  37 +++++
 .../externals/reference/FieldReference.java     |  17 +-
 .../externals/reference/MethodReference.java    |  13 +-
 .../externals/reference/ReferenceModel.java     |  33 +++-
 .../codegen/externals/utils/DebugLogUtils.java  |   4 +-
 7 files changed, 243 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
index edc9d1e..c435a03 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java
@@ -19,11 +19,14 @@
 
 package org.apache.flex.compiler.internal.codegen.externals;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 
 import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
 import org.junit.Test;
 
 import com.google.javascript.jscomp.Result;
@@ -36,11 +39,110 @@ public class TestExternChrome extends ExternalsTestBase
         client.cleanOutput();
         Result result = compile();
         assertTrue(result.success);
+
+        String[] classes = {
+                "chrome",
+                "chrome.app",
+                "chrome.webstore",
+                "chrome.runtime",
+                "chrome.runtime.lastError",
+
+                "Port",
+                "ChromeEvent",
+                "ChromeStringEvent",
+                "ChromeBooleanEvent",
+                "ChromeNumberEvent",
+                "ChromeObjectEvent",
+                "ChromeStringArrayEvent",
+                "ChromeStringStringEvent",
+                "MessageSender",
+                "Tab",
+                "ChromeLoadTimes",
+                "ChromeCsiInfo" };
+
+        assertEquals(17, model.getClasses().size());
+        for (String className : classes)
+        {
+            assertTrue(model.hasClass(className));
+        }
+
         client.emit();
     }
 
+    @Test
+    public void test_members() throws IOException
+    {
+        client.cleanOutput();
+        Result result = compile();
+        assertTrue(result.success);
+
+        // Port
+        ClassReference Port = model.getClassReference("Port");
+        assertNotNull(Port);
+        assertTrue(Port.hasInstanceField("name"));
+        assertTrue(Port.hasInstanceField("onDisconnect"));
+        assertTrue(Port.hasInstanceField("onMessage"));
+        assertTrue(Port.hasInstanceField("sender"));
+
+        assertTrue(Port.hasInstanceMethod("postMessage"));
+        assertTrue(Port.hasInstanceMethod("disconnect"));
+
+        assertEquals("string", Port.getField("name").toTypeAnnotationString());
+        assertEquals("ChromeEvent",
+                Port.getField("onDisconnect").toTypeAnnotationString());
+        assertEquals("ChromeEvent",
+                Port.getField("onMessage").toTypeAnnotationString());
+        assertEquals("(MessageSender|undefined)",
+                Port.getField("sender").toTypeAnnotationString());
+
+        // chrome
+        ClassReference chrome = model.getClassReference("chrome");
+        assertNotNull(chrome);
+        assertTrue(chrome.hasStaticMethod("loadTimes"));
+        assertTrue(chrome.hasStaticMethod("csi"));
+        assertEquals("ChromeLoadTimes",
+                chrome.getMethod("loadTimes").toReturnTypeAnnotationString());
+        assertEquals("ChromeCsiInfo",
+                chrome.getMethod("csi").toReturnTypeAnnotationString());
+
+        // chrome.app
+        ClassReference chrome_app = model.getClassReference("chrome.app");
+        assertNotNull(chrome_app);
+        assertTrue(chrome_app.hasInstanceField("isInstalled"));
+        assertEquals("boolean",
+                chrome_app.getField("isInstalled").toTypeAnnotationString());
+
+        // chrome.runtime
+        ClassReference chrome_runtime = model.getClassReference("chrome.runtime");
+        assertNotNull(chrome_runtime);
+        assertTrue(chrome_runtime.hasInstanceMethod("connect"));
+        assertTrue(chrome_runtime.hasInstanceMethod("sendMessage"));
+
+        // chrome.runtime.lastError
+        ClassReference chrome_runtime_lastError = model.getClassReference("chrome.runtime.lastError");
+        assertNotNull(chrome_runtime_lastError);
+        assertTrue(chrome_runtime_lastError.hasInstanceField("message"));
+        assertEquals(
+                "(string|undefined)",
+                chrome_runtime_lastError.getField("message").toTypeAnnotationString());
+
+        // chrome.webstore
+        ClassReference chrome_webstore = model.getClassReference("chrome.webstore");
+        assertNotNull(chrome_webstore);
+        assertTrue(chrome_webstore.hasInstanceField("onInstallStageChanged"));
+        assertTrue(chrome_webstore.hasInstanceField("onDownloadProgress"));
+        assertTrue(chrome_webstore.hasInstanceMethod("install"));
+
+        // Code generated
+        assertTrue(chrome.hasStaticField("app"));
+        assertTrue(chrome.hasStaticField("runtime"));
+        assertTrue(chrome.hasStaticField("webstore"));
+
+        assertTrue(chrome_runtime.hasInstanceField("lastError"));
+    }
+
     @Override
-    protected void configure(ExternCConfiguration config) throws IOException
+    protected void configure(ExternCConfiguration install) throws IOException
     {
         config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
index 7213b5a..d08f9b1 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
@@ -19,7 +19,6 @@
 
 package org.apache.flex.compiler.internal.codegen.externals.pass;
 
-import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
 import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
 
 import com.google.javascript.jscomp.AbstractCompiler;
@@ -75,77 +74,9 @@ public class AddMemberPass extends AbstractCompilerPass
             }
             else if (n.isGetProp())
             {
-                //log(n.toStringTree());
-                log(n.getQualifiedName());
-
-                String qName = n.getQualifiedName();
-                // Port.prototype.name
-
-                // chrome.runtime.lastError.message
-                int protoType = qName.indexOf(".prototype");
-                if (protoType != -1)
-                {
-                    String className = qName.substring(0, protoType);
-                    String memberName = qName.substring(protoType + 11,
-                            qName.length());
-                    log("Prototype:: className [" + className
-                            + "] memberName [" + memberName + "]");
-                    model.addField(n, className, memberName);
-                }
-                else
-                {
-                    String className = qName.substring(0,
-                            qName.lastIndexOf("."));
-                    String memberName = qName.substring(
-                            qName.lastIndexOf(".") + 1, qName.length());
-                    log("className [" + className + "] memberName ["
-                            + memberName + "]");
-                    model.addStaticField(n, className, memberName);
-                }
-
-                //                if (n.getFirstChild().isName())
-                //                {
-                //                    visitStaticField(t, n);
-                //                    //System.err.println(n.toStringTree());
-                //                }
-                //                else if (n.getFirstChild().isGetProp())
-                //                {
-                //                    try
-                //                    {
-                //                        if (n.getFirstChild().getFirstChild().isGetProp())
-                //                        {
-                //                            // XXX TODO qualified class names 'chrome.runtime.lastError
'
-                //                        }
-                //                        else
-                //                        {
-                //                            visitInstanceField(t, n);
-                //                        }
-                //
-                //                    }
-                //                    catch (Exception e)
-                //                    {
-                //
-                //                        /*
-                //                         * 
-                //                        GETPROP 438 [jsdoc_info: JSDocInfo] [source_file:
[chrome]] [length: 32]
-                //                        GETPROP 438 [source_file: [chrome]] [length: 24]
-                //                        GETPROP 438 [source_file: [chrome]] [length: 14]
-                //                        NAME chrome 438 [source_file: [chrome]] [length:
6]
-                //                        STRING runtime 438 [source_file: [chrome]] [length:
7]
-                //                        STRING lastError 438 [source_file: [chrome]] [length:
9]
-                //                        STRING message 438 [source_file: [chrome]] [length:
7]
-                //                         * 
-                //                         */
-                //                        // TODO Auto-generated catch block
-                //                        System.err.println(n.toStringTree());
-                //                        e.printStackTrace();
-                //                    }
-                //                }
-
-                // System.err.println(n.toStringTree());
+                visitGetProp(t, n);
             }
         }
-
     }
 
     /*
@@ -211,66 +142,66 @@ public class AddMemberPass extends AbstractCompilerPass
     */
 
     // n == ASSIGN
-    @SuppressWarnings("unused")
     private void visitMethod(NodeTraversal t, Node n)
     {
-        JSDocInfo jsDoc = n.getJSDocInfo();
-        if (jsDoc == null)
-        {
-            // XXX Waring
-            return;
-        }
-
-        //System.out.println(n.toStringTree());
-        Node getProp = n.getFirstChild();
-        Node getProp2 = getProp.getFirstChild();
-
-        Node function = n.getLastChild();
+        String qName = n.getFirstChild().getQualifiedName();
 
-        Node className = getProp2.getFirstChild();
-        Node prototype = getProp2.getLastChild(); // check for static
-        Node functionName = getProp.getLastChild();
-
-        //Node name = function.getChildAtIndex(0);
-        Node paramList = function.getChildAtIndex(1);
-        //        if (!getProp.isQualifiedName())
-        //        {
-        //
-        //        }
-
-        if (getProp.getFirstChild().isGetProp())
+        if (n.getFirstChild().isGetProp())
         {
-            ClassReference classReference = model.findClassReference(className.getString());
-            if (classReference != null)
+            int protoType = qName.indexOf(".prototype");
+            if (protoType != -1)
             {
-                classReference.addMethod(n, functionName.getString(), jsDoc,
-                        false);
+                String className = qName.substring(0, protoType);
+                String memberName = qName.substring(protoType + 11,
+                        qName.length());
+                //log("Prototype:: className [" + className
+                //        + "] memberName [" + memberName + "]");
+                model.addMethod(n, className, memberName);
             }
             else
             {
-
-                err(">>>> {AddMemberPass.addMethod()} Class [" + className
-                        + "] not found in " + n.getSourceFileName());
+                String className = qName.substring(0, qName.lastIndexOf("."));
+                String memberName = qName.substring(qName.lastIndexOf(".") + 1,
+                        qName.length());
+                //log("className [" + className + "] memberName ["
+                //        + memberName + "]");
+                model.addStaticMethod(n, className, memberName);
             }
         }
-        else if (getProp.getFirstChild().isName())
+        else if (n.getFirstChild().isName())
         {
-            className = getProp.getFirstChild();
-            functionName = getProp.getLastChild(); // Same
+            log(n);
+        }
+    }
 
-            //System.err.println(n.toStringTree());
-            ClassReference classReference = model.findClassReference(className.getString());
-            if (classReference != null)
-            {
-                classReference.addMethod(n, functionName.getString(), jsDoc,
-                        true);
-            }
-            else
-            {
-                err(">>>> {AddMemberPass.addMethod()} Class [" + className
-                        + "] not found in " + n.getSourceFileName());
-            }
+    private void visitGetProp(NodeTraversal t, Node n)
+    {
+        //log(n.toStringTree());
+        log(n.getQualifiedName());
+
+        String qName = n.getQualifiedName();
+        // Port.prototype.name
+
+        // chrome.runtime.lastError.message
+        int protoType = qName.indexOf(".prototype");
+        if (protoType != -1)
+        {
+            String className = qName.substring(0, protoType);
+            String memberName = qName.substring(protoType + 11, qName.length());
+            //log("Prototype:: className [" + className
+            //        + "] memberName [" + memberName + "]");
+            model.addField(n, className, memberName);
+        }
+        else
+        {
+            String className = qName.substring(0, qName.lastIndexOf("."));
+            String memberName = qName.substring(qName.lastIndexOf(".") + 1,
+                    qName.length());
+            //log("className [" + className + "] memberName ["
+            //        + memberName + "]");
+            model.addStaticField(n, className, memberName);
         }
+
     }
 
     /*

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
index 9aa4255..880d2da 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
@@ -77,6 +77,11 @@ public class ClassReference extends BaseReference
         return methods;
     }
 
+    public FieldReference getField(String name)
+    {
+        return fields.get(name);
+    }
+
     public MethodReference getMethod(String name)
     {
         return methods.get(name);
@@ -250,11 +255,43 @@ public class ClassReference extends BaseReference
         return fields.containsKey(fieldName);
     }
 
+    public boolean hasInstanceField(String fieldName)
+    {
+        if (!fields.containsKey(fieldName))
+            return false;
+
+        return !fields.get(fieldName).isStatic();
+    }
+
+    public boolean hasStaticField(String fieldName)
+    {
+        if (!fields.containsKey(fieldName))
+            return false;
+
+        return fields.get(fieldName).isStatic();
+    }
+
     public boolean hasMethod(String methodName)
     {
         return methods.containsKey(methodName);
     }
 
+    public boolean hasInstanceMethod(String fieldName)
+    {
+        if (!methods.containsKey(fieldName))
+            return false;
+
+        return !methods.get(fieldName).isStatic();
+    }
+
+    public boolean hasStaticMethod(String fieldName)
+    {
+        if (!methods.containsKey(fieldName))
+            return false;
+
+        return methods.get(fieldName).isStatic();
+    }
+
     public MethodReference addMethod(Node node, String functionName,
             JSDocInfo comment, boolean isStatic)
     {

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
index cd2804a..a857260 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
@@ -26,6 +26,7 @@ import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
 import com.google.javascript.rhino.JSDocInfo;
 import com.google.javascript.rhino.JSTypeExpression;
 import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType;
 
 public class FieldReference extends MemberReference
 {
@@ -43,6 +44,18 @@ public class FieldReference extends MemberReference
         this.isStatic = isStatic;
     }
 
+    public void setOverrideStringType(String overrideStringType)
+    {
+        this.overrideStringType = overrideStringType;
+    }
+
+    public String toTypeAnnotationString()
+    {
+        JSType jsType = getComment().getType().evaluate(null,
+                getModel().getCompiler().getTypeRegistry());
+        return jsType.toAnnotationString();
+    }
+
     public FieldReference(ReferenceModel model, ClassReference classReference,
             Node node, String name, JSDocInfo comment, boolean isStatic)
     {
@@ -150,8 +163,4 @@ public class FieldReference extends MemberReference
 
     }
 
-    public void setOverrideStringType(String overrideStringType)
-    {
-        this.overrideStringType = overrideStringType;
-    }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
index 0103a31..42e700a 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
@@ -26,6 +26,7 @@ import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
 
 import com.google.javascript.rhino.JSDocInfo;
 import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType;
 
 public class MethodReference extends MemberReference
 {
@@ -44,14 +45,21 @@ public class MethodReference extends MemberReference
         return isStatic;
     }
 
+    public void setStatic(boolean isStatic)
+    {
+        this.isStatic = isStatic;
+    }
+
     public Set<String> getParameterNames()
     {
         return getComment().getParameterNames();
     }
 
-    public void setStatic(boolean isStatic)
+    public String toReturnTypeAnnotationString()
     {
-        this.isStatic = isStatic;
+        JSType jsType = getComment().getReturnType().evaluate(null,
+                getModel().getCompiler().getTypeRegistry());
+        return jsType.toAnnotationString();
     }
 
     public MethodReference(ReferenceModel model, ClassReference classReference,
@@ -177,4 +185,5 @@ public class MethodReference extends MemberReference
     {
         emitFunctionCommentBody(sb);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
index 7751f4b..9d44d21 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
@@ -252,15 +252,15 @@ public class ReferenceModel
         constants.put(qName, reference);
     }
 
-    public void addField(Node node, String className, String qualfiedName)
+    public void addField(Node node, String className, String memberName)
     {
         ClassReference classReference = getClassReference(className);
         if (classReference != null)
-            classReference.addField(node, qualfiedName, node.getJSDocInfo(),
+            classReference.addField(node, memberName, node.getJSDocInfo(),
                     false);
     }
 
-    public void addStaticField(Node node, String className, String qualfiedName)
+    public void addStaticField(Node node, String className, String memberName)
     {
         ClassReference classReference = findClassReference(className);
         // XXX this is here because for now, the doc might be on the parent ASSIGN node
@@ -268,7 +268,32 @@ public class ReferenceModel
         JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
         if (classReference != null)
         {
-            classReference.addField(node, qualfiedName, comment, true);
+            classReference.addField(node, memberName, comment, true);
+        }
+        else
+        {
+            err(">>>> {ReferenceModel} Class [" + className + "] not found in
"
+                    + node.getSourceFileName());
+        }
+    }
+
+    public void addMethod(Node node, String className, String memberName)
+    {
+        ClassReference classReference = getClassReference(className);
+        if (classReference != null)
+            classReference.addMethod(node, memberName, node.getJSDocInfo(),
+                    false);
+    }
+
+    public void addStaticMethod(Node node, String className, String memberName)
+    {
+        ClassReference classReference = findClassReference(className);
+        // XXX this is here because for now, the doc might be on the parent ASSIGN node
+        // if it's a static property with a value
+        JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+        if (classReference != null)
+        {
+            classReference.addMethod(node, memberName, comment, true);
         }
         else
         {

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
index 5dcdc48..856df40 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
@@ -23,8 +23,8 @@ import com.google.javascript.rhino.Node;
 
 public final class DebugLogUtils
 {
-    private static boolean logEnabled = false;
-    private static boolean errEnabled = false;
+    private static boolean logEnabled = true;
+    private static boolean errEnabled = true;
 
     public static void log(Node n)
     {


Mime
View raw message