You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2020/10/21 18:44:10 UTC

[sling-org-apache-sling-scripting-sightly-compiler] branch issue/SLING-9829 created (now ec8ed4b)

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

radu pushed a change to branch issue/SLING-9829
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler.git.


      at ec8ed4b  SLING-9829 - data-sly-element should correctly handle void elements

This branch includes the following new commits:

     new ec8ed4b  SLING-9829 - data-sly-element should correctly handle void elements

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-org-apache-sling-scripting-sightly-compiler] 01/01: SLING-9829 - data-sly-element should correctly handle void elements

Posted by ra...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

radu pushed a commit to branch issue/SLING-9829
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler.git

commit ec8ed4b444e5cb37c4682b2a885d9b0a2a04d12d
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Wed Oct 21 20:33:58 2020 +0200

    SLING-9829 - data-sly-element should correctly handle void elements
    
    * defined the set of void elements in ElementPlugin; every time the
    data-sly-element plugin is used, the dynamically passed tag name will
    be checked against the set; if the tag is a void element, no closing tag
    will be added
---
 .../compiler/expression/nodes/StringConstant.java  | 18 +++++
 .../compiler/expression/nodes/package-info.java    |  2 +-
 .../impl/compiler/frontend/CompilerContext.java    |  4 ++
 .../impl/compiler/util/SymbolGenerator.java        | 11 +++-
 .../sightly/impl/plugin/ElementPlugin.java         | 77 +++++++++++++++++-----
 5 files changed, 94 insertions(+), 18 deletions(-)

diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/StringConstant.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/StringConstant.java
index 2862490..4a6501f 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/StringConstant.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/StringConstant.java
@@ -18,6 +18,8 @@
  ******************************************************************************/
 package org.apache.sling.scripting.sightly.compiler.expression.nodes;
 
+import java.util.Objects;
+
 import org.apache.sling.scripting.sightly.compiler.expression.NodeVisitor;
 
 /**
@@ -63,4 +65,20 @@ public final class StringConstant implements Atom {
                 '}';
     }
 
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(text);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StringConstant) {
+            StringConstant other = (StringConstant) obj;
+            return Objects.equals(text, other.text);
+        }
+        return false;
+    }
 }
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java
index e2c21a3..efda58f 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/expression/nodes/package-info.java
@@ -19,7 +19,7 @@
  * The {@code org.apache.sling.scripting.sightly.compiler.expression.nodes} package exposes the various
  * {@link org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode} types.
  */
-@Version("1.2.0")
+@Version("1.2.1")
 package org.apache.sling.scripting.sightly.compiler.expression.nodes;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
index 6096c20..9df6c3b 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
@@ -45,6 +45,10 @@ public class CompilerContext {
         return symbolGenerator.next(hint);
     }
 
+    public String generateGlobalVariable(String hint) {
+        return symbolGenerator.global(hint);
+    }
+
     public Expression adjustToContext(Expression expression, MarkupContext context, ExpressionContext expressionContext) {
         return expressionWrapper.adjustToContext(expression, context, expressionContext);
     }
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java
index 6277b1f..39b11bf 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/util/SymbolGenerator.java
@@ -18,12 +18,16 @@
  ******************************************************************************/
 package org.apache.sling.scripting.sightly.impl.compiler.util;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public class SymbolGenerator {
 
     public static final String DEFAULT_VAR_PREFIX = "var_";
 
     private int counter = 0;
     private final String prefix;
+    private final Map<String, String> globals = new HashMap<>();
 
     public SymbolGenerator() {
         this(DEFAULT_VAR_PREFIX);
@@ -34,10 +38,15 @@ public class SymbolGenerator {
     }
 
     public String next(String hint) {
-        String middle = (hint != null) ? hint.replaceAll("\\-", "_") : "";
+        String middle = (hint != null) ? hint.replace("-", "_") : "";
         return prefix + middle + counter++;
     }
 
+    public String global(String hint) {
+        String name = prefix +  ((hint != null) ? hint.replace("-", "_") : "");
+        return globals.computeIfAbsent(name, key -> name + counter++);
+    }
+
     public String next() {
         return next(null);
     }
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java
index 29439b1..9a58ef2 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ElementPlugin.java
@@ -18,6 +18,12 @@
  ******************************************************************************/
 package org.apache.sling.scripting.sightly.impl.plugin;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 import org.apache.sling.scripting.sightly.compiler.commands.Conditional;
 import org.apache.sling.scripting.sightly.compiler.commands.OutText;
 import org.apache.sling.scripting.sightly.compiler.commands.OutputVariable;
@@ -25,7 +31,14 @@ import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
 import org.apache.sling.scripting.sightly.compiler.expression.Expression;
 import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
 import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.ArrayLiteral;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
 import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperation;
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperator;
 import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
 import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
 import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
@@ -36,27 +49,40 @@ public class ElementPlugin extends AbstractPlugin {
         name = "element";
     }
 
+    public static final Set<ExpressionNode> VOID_ELEMENTS =
+            Collections.unmodifiableSet(new HashSet<>(
+                    Arrays.asList(new StringConstant("area"), new StringConstant("base"), new StringConstant("br"),
+                            new StringConstant("col"), new StringConstant("embed"), new StringConstant("hr"), new StringConstant("img"),
+                            new StringConstant("input"), new StringConstant("link"), new StringConstant("meta"),
+                            new StringConstant("param"), new StringConstant("source"), new StringConstant("track"),
+                            new StringConstant("wbr"))));
+
     @Override
     public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) {
 
         return new DefaultPluginInvoke() {
 
-            private final ExpressionNode node = adjustContext(compilerContext, expression, MarkupContext.ELEMENT_NAME, ExpressionContext
-                    .ELEMENT).getRoot();
-            private String tagVar = compilerContext.generateVariable("tagVar");
+            private final ExpressionNode node = adjustContext(compilerContext, expression).getRoot();
+            private final String tagVar = compilerContext.generateVariable("tagVar");
+            private final String tagAllowed = compilerContext.generateVariable("tagAllowed");
+            private final String voidElements = compilerContext.generateGlobalVariable("elementPluginVoidElements");
+            private final String selfClosingTag = compilerContext.generateVariable("selfClosingTag");
 
             @Override
             public void beforeElement(PushStream stream, String tagName) {
+                stream.write(new VariableBinding.Global(voidElements, new ArrayLiteral(new ArrayList<>(VOID_ELEMENTS))));
                 stream.write(new VariableBinding.Start(tagVar, node));
+                stream.write(new VariableBinding.Start(tagAllowed, new UnaryOperation(UnaryOperator.NOT,
+                        new UnaryOperation(UnaryOperator.NOT, new Identifier(tagVar)))));
             }
 
             @Override
             public void beforeTagOpen(PushStream stream) {
-                stream.write(new Conditional.Start(tagVar, true));
+                stream.write(new Conditional.Start(tagAllowed, true));
                 stream.write(new OutText("<"));
                 stream.write(new OutputVariable(tagVar));
                 stream.write(Conditional.END);
-                stream.write(new Conditional.Start(tagVar, false));
+                stream.write(new Conditional.Start(tagAllowed, false));
             }
 
             @Override
@@ -65,15 +91,34 @@ public class ElementPlugin extends AbstractPlugin {
             }
 
             @Override
+            public void afterAttributes(PushStream stream) {
+                stream.write(new Conditional.Start(tagAllowed, true));
+                stream.write(new OutText(">"));
+                stream.write(Conditional.END);
+                stream.write(new Conditional.Start(tagAllowed, false));
+            }
+
+            @Override
+            public void afterTagOpen(PushStream stream) {
+                stream.write(Conditional.END);
+            }
+
+            @Override
             public void beforeTagClose(PushStream stream, boolean isSelfClosing) {
-                if (!isSelfClosing) {
-                    stream.write(new Conditional.Start(tagVar, true));
-                    stream.write(new OutText("</"));
-                    stream.write(new OutputVariable(tagVar));
-                    stream.write(new OutText(">"));
-                    stream.write(Conditional.END);
-                }
-                stream.write(new Conditional.Start(tagVar, false));
+                stream.write(new Conditional.Start(tagAllowed, true));
+                stream.write(
+                        new VariableBinding.Start(selfClosingTag,
+                                new BinaryOperation(BinaryOperator.IN, new Identifier(tagVar), new Identifier(voidElements))
+                        )
+                );
+                stream.write(new Conditional.Start(selfClosingTag, false));
+                stream.write(new OutText("</"));
+                stream.write(new OutputVariable(tagVar));
+                stream.write(new OutText(">"));
+                stream.write(Conditional.END);
+                stream.write(VariableBinding.END);
+                stream.write(Conditional.END);
+                stream.write(new Conditional.Start(tagAllowed, false));
             }
 
             @Override
@@ -84,13 +129,13 @@ public class ElementPlugin extends AbstractPlugin {
             @Override
             public void afterElement(PushStream stream) {
                 stream.write(VariableBinding.END);
+                stream.write(VariableBinding.END);
             }
         };
 
     }
 
-    private Expression adjustContext(CompilerContext compilerContext, Expression expression, MarkupContext markupContext,
-                                     ExpressionContext expressionContext) {
+    private Expression adjustContext(CompilerContext compilerContext, Expression expression) {
         ExpressionNode root = expression.getRoot();
         if (root instanceof RuntimeCall) {
             RuntimeCall runtimeCall = (RuntimeCall) root;
@@ -98,6 +143,6 @@ public class ElementPlugin extends AbstractPlugin {
                 return expression;
             }
         }
-        return compilerContext.adjustToContext(expression, markupContext, expressionContext);
+        return compilerContext.adjustToContext(expression, MarkupContext.ELEMENT_NAME, ExpressionContext.ELEMENT);
     }
 }