You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2014/11/28 11:18:09 UTC
svn commit: r1642281 [6/14] - in /sling/trunk/contrib/scripting/sightly: ./
engine/ engine/src/main/antlr4/org/apache/sling/parser/expr/generated/
engine/src/main/antlr4/org/apache/sling/scripting/
engine/src/main/antlr4/org/apache/sling/scripting/sigh...
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/TernaryOperator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/TernaryOperator.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/TernaryOperator.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/TernaryOperator.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.expression.node;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.NodeVisitor;
+
+/**
+ * Defines the Sightly ternary operator: {@code condition ? then : else}.
+ */
+public class TernaryOperator implements ExpressionNode {
+
+ private ExpressionNode condition;
+ private ExpressionNode thenBranch;
+ private ExpressionNode elseBranch;
+
+ public TernaryOperator(ExpressionNode condition, ExpressionNode thenBranch, ExpressionNode elseBranch) {
+ this.condition = condition;
+ this.thenBranch = thenBranch;
+ this.elseBranch = elseBranch;
+ }
+
+ public ExpressionNode getCondition() {
+ return condition;
+ }
+
+ public ExpressionNode getThenBranch() {
+ return thenBranch;
+ }
+
+ public ExpressionNode getElseBranch() {
+ return elseBranch;
+ }
+
+ @Override
+ public <T> T accept(NodeVisitor<T> visitor) {
+ return visitor.evaluate(this);
+ }
+
+ @Override
+ public String toString() {
+ return "TernaryOperator{" +
+ "condition=" + condition +
+ ", thenBranch=" + thenBranch +
+ ", elseBranch=" + elseBranch +
+ '}';
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/TernaryOperator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperation.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperation.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperation.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.expression.node;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.NodeVisitor;
+
+/**
+ * Defines a unary operation (e.g. !variableName).
+ */
+public class UnaryOperation implements ExpressionNode {
+
+ private UnaryOperator operator;
+ private ExpressionNode target;
+
+ public UnaryOperation(UnaryOperator operator, ExpressionNode target) {
+ this.operator = operator;
+ this.target = target;
+ }
+
+ @Override
+ public <T> T accept(NodeVisitor<T> visitor) {
+ return visitor.evaluate(this);
+ }
+
+ public UnaryOperator getOperator() {
+ return operator;
+ }
+
+ public ExpressionNode getTarget() {
+ return target;
+ }
+
+ @Override
+ public String toString() {
+ return "UnaryOperation{" +
+ "operator=" + operator +
+ ", operand=" + target +
+ '}';
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperation.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperator.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperator.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperator.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.expression.node;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Unary operators used in expressions
+ */
+public enum UnaryOperator {
+
+ /** Evaluates to logical negation of the operand */
+ NOT {
+ @Override
+ public Object eval(RenderContext renderContext, Object operand) {
+ return !renderContext.toBoolean(operand);
+ }
+ },
+
+ /** Evaluates whether the operand is a string of only whitespace characters */
+ IS_WHITESPACE {
+ @Override
+ public Object eval(RenderContext renderContext, Object operand) {
+ return StringUtils.isWhitespace(renderContext.toString(operand));
+ }
+ },
+
+ /**
+ * Evaluates the length of a collection
+ */
+ LENGTH {
+ @Override
+ public Object eval(RenderContext renderContext, Object operand) {
+ return renderContext.toCollection(operand).size();
+ }
+ };
+
+ public abstract Object eval(RenderContext model, Object operand);
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/expression/node/UnaryOperator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/AggregatePluginInvoke.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/AggregatePluginInvoke.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/AggregatePluginInvoke.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/AggregatePluginInvoke.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import java.util.List;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.impl.plugin.PluginInvoke;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+
+/**
+ * Plugin invoke which aggregates the behavior of several plugin invokes
+ */
+public class AggregatePluginInvoke implements PluginInvoke {
+
+ private final List<PluginInvoke> invokes;
+
+ public AggregatePluginInvoke(List<PluginInvoke> invokes) {
+ this.invokes = invokes;
+ }
+
+ @Override
+ public void beforeElement(PushStream stream, String tagName) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeElement(stream, tagName);
+ }
+ }
+
+ @Override
+ public void beforeTagOpen(PushStream stream) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeTagOpen(stream);
+ }
+ }
+
+ @Override
+ public void beforeAttributes(PushStream stream) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeAttributes(stream);
+ }
+ }
+
+ @Override
+ public void beforeAttribute(PushStream stream, String attributeName) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeAttribute(stream, attributeName);
+ }
+ }
+
+ @Override
+ public void beforeAttributeValue(PushStream stream, String attributeName, ExpressionNode attributeValue) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeAttributeValue(stream, attributeName, attributeValue);
+ }
+ }
+
+ @Override
+ public void afterAttributeValue(PushStream stream, String attributeName) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterAttributeValue(stream, attributeName);
+ }
+ }
+
+ @Override
+ public void afterAttribute(PushStream stream, String attributeName) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterAttribute(stream, attributeName);
+ }
+ }
+
+ @Override
+ public void onPluginCall(PushStream stream, PluginCallInfo callInfo, Expression expression) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.onPluginCall(stream, callInfo, expression);
+ }
+ }
+
+ @Override
+ public void afterAttributes(PushStream stream) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterAttributes(stream);
+ }
+ }
+
+ @Override
+ public void afterTagOpen(PushStream stream) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterTagOpen(stream);
+ }
+ }
+
+ @Override
+ public void beforeChildren(PushStream stream) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeChildren(stream);
+ }
+ }
+
+ @Override
+ public void afterChildren(PushStream stream) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterChildren(stream);
+ }
+ }
+
+ @Override
+ public void beforeTagClose(PushStream stream, boolean isSelfClosing) {
+ for (PluginInvoke invoke : invokes) {
+ invoke.beforeTagClose(stream, isSelfClosing);
+ }
+ }
+
+ @Override
+ public void afterTagClose(PushStream stream, boolean isSelfClosing) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterTagClose(stream, isSelfClosing);
+ }
+ }
+
+ @Override
+ public void afterElement(PushStream stream) {
+ for (int i = invokes.size() - 1; i >= 0; i--) {
+ PluginInvoke invoke = invokes.get(i);
+ invoke.afterElement(stream);
+ }
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/AggregatePluginInvoke.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.plugin.MarkupContext;
+import org.apache.sling.scripting.sightly.impl.compiler.util.SymbolGenerator;
+
+
+/**
+ * Default implementation for the compiler context
+ * @see org.apache.sling.scripting.sightly.impl.plugin.Plugin
+ */
+public class CompilerContext {
+
+ private SymbolGenerator symbolGenerator;
+ private ExpressionWrapper expressionWrapper;
+
+ public CompilerContext(SymbolGenerator symbolGenerator, ExpressionWrapper wrapper) {
+ this.symbolGenerator = symbolGenerator;
+ this.expressionWrapper = wrapper;
+ }
+
+ public String generateVariable(String hint) {
+ return symbolGenerator.next(hint);
+ }
+
+ public Expression adjustToContext(Expression expression, MarkupContext context) {
+ if (!expression.getOptions().containsKey(Syntax.CONTEXT_OPTION)) {
+ return expressionWrapper.adjustToContext(expression, context);
+ }
+ return expression;
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ElementContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ElementContext.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ElementContext.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ElementContext.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.plugin.PluginCallInfo;
+import org.apache.sling.scripting.sightly.impl.plugin.PluginInvoke;
+
+/**
+ * Data structure used by {@link MarkupHandler}.
+ */
+public class ElementContext {
+ private final String tagName;
+ private final String openTagStartMarkup;
+
+ private final List<PrioritizedInvoke> invokeList = new ArrayList<PrioritizedInvoke>();
+ private final List<Map.Entry<String, Object>> attributes = new ArrayList<Map.Entry<String, Object>>();
+ private PluginInvoke aggregateInvoke;
+
+ public ElementContext(String tagName, String openTagStartMarkup) {
+ this.tagName = tagName;
+ this.openTagStartMarkup = openTagStartMarkup;
+ }
+
+ public String getTagName() {
+ return tagName;
+ }
+
+ public String getOpenTagStartMarkup() {
+ return openTagStartMarkup;
+ }
+
+ public void addPlugin(PluginInvoke invoke, int priority) {
+ invokeList.add(new PrioritizedInvoke(invoke, priority));
+ }
+
+ public void addAttribute(String name, String value) {
+ attributes.add(new AbstractMap.SimpleEntry<String, Object>(name, value));
+ }
+
+ public void addPluginCall(String name, PluginCallInfo info, Expression expression) {
+ attributes.add(new AbstractMap.SimpleEntry<String, Object>(name,
+ new AbstractMap.SimpleEntry<PluginCallInfo, Expression>(info, expression)));
+ }
+
+ public Iterable<Map.Entry<String, Object>> getAttributes() {
+ return attributes;
+ }
+
+ public PluginInvoke pluginInvoke() {
+ if (aggregateInvoke == null) {
+ Collections.sort(invokeList);
+ ArrayList<PluginInvoke> result = new ArrayList<PluginInvoke>();
+ for (PrioritizedInvoke prioritizedInvoke : invokeList) {
+ result.add(prioritizedInvoke.invoke);
+ }
+ aggregateInvoke = new AggregatePluginInvoke(result);
+ }
+ return aggregateInvoke;
+ }
+
+
+ private static final class PrioritizedInvoke implements Comparable<PrioritizedInvoke> {
+
+ private final PluginInvoke invoke;
+ private final int priority;
+
+ private PrioritizedInvoke(PluginInvoke invoke, int priority) {
+ this.invoke = invoke;
+ this.priority = priority;
+ }
+
+ @Override
+ public int compareTo(PrioritizedInvoke o) {
+ if (this.priority < o.priority) {
+ return -1;
+ } else if (this.priority == o.priority) {
+ return 0;
+ }
+ return 1;
+ }
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ElementContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionParser.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionParser.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionParser.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionParser.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.RecognitionException;
+import org.apache.sling.scripting.sightly.impl.parser.expr.generated.SightlyLexer;
+import org.apache.sling.scripting.sightly.impl.parser.expr.generated.SightlyParser;
+
+public class ExpressionParser {
+
+ /**
+ * Parses the expression string.
+ *
+ * @param expressionString as defined by the Sightly spec (https://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/master/SPECIFICATION.md)
+ * @return Parsed Expression object
+ * @throws NullPointerException is the given exprString is null
+ * @throws ParserException if an error occurs while parsing the expression
+ */
+ public Interpolation parseInterpolation(String expressionString) throws ParserException {
+ SightlyParser parser = createParser(expressionString);
+ try {
+ return parser.interpolation().interp;
+ } catch (RecognitionException e) {
+ throw new ParserException(e);
+ }
+ }
+
+ private SightlyParser createParser(String string) {
+ SightlyLexer lexer = new SightlyLexer(new ANTLRInputStream(string));
+ CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+ SightlyParser parser = new SightlyParser(tokenStream);
+ parser.removeErrorListeners();
+ parser.addErrorListener(new SightlyParserErrorListener());
+ return parser;
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionParser.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.filter.Filter;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BinaryOperator;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.impl.plugin.MarkupContext;
+
+/**
+ * This object wraps expressions in filter applications depending
+ * on options
+ */
+public class ExpressionWrapper {
+
+ private final List<Filter> filters;
+
+ public ExpressionWrapper(Collection<Filter> filters) {
+ this.filters = new ArrayList<Filter>();
+ this.filters.addAll(filters);
+ Collections.sort(this.filters);
+ }
+
+ public Expression transform(Interpolation interpolation, MarkupContext markupContext) {
+ ArrayList<ExpressionNode> nodes = new ArrayList<ExpressionNode>();
+ HashMap<String, ExpressionNode> options = new HashMap<String, ExpressionNode>();
+ for (Fragment fragment : interpolation.getFragments()) {
+ if (fragment.isString()) {
+ nodes.add(new StringConstant(fragment.getText()));
+ } else {
+ Expression expression = fragment.getExpression();
+ options.putAll(expression.getOptions());
+ nodes.add(transformExpr(expression, markupContext).getRoot());
+ }
+ }
+ ExpressionNode root = join(nodes);
+ if (interpolation.size() > 1 && options.containsKey(Syntax.CONTEXT_OPTION)) {
+ //context must not be calculated by merging
+ options.remove(Syntax.CONTEXT_OPTION);
+ }
+ return new Expression(root, options);
+ }
+
+ private Expression applyFilters(Expression expression) {
+ Expression result = expression;
+ for (Filter filter : filters) {
+ result = filter.apply(result);
+ }
+ return result;
+ }
+
+ public Expression adjustToContext(Expression expression, MarkupContext markupContext) {
+ if (expression.containsOption(Syntax.CONTEXT_OPTION)) {
+ return expression;
+ }
+ Map<String, ExpressionNode> opt = addDefaultContext(Collections.<String, ExpressionNode>emptyMap(), markupContext);
+ Expression result = applyFilters(new Expression(expression.getRoot(), opt));
+ return expression.withNode(result.getRoot());
+ }
+
+ private ExpressionNode join(List<ExpressionNode> nodes) {
+ if (nodes.isEmpty()) {
+ return StringConstant.EMPTY;
+ }
+ ExpressionNode root = nodes.get(0);
+ for (int i = 1; i < nodes.size(); i++) {
+ ExpressionNode node = nodes.get(i);
+ root = new BinaryOperation(BinaryOperator.CONCATENATE, root, node);
+ }
+ return root;
+ }
+
+ private Expression transformExpr(Expression expression, MarkupContext markupContext) {
+ expression = addDefaultContext(expression, markupContext);
+ return applyFilters(expression);
+ }
+
+ private Expression addDefaultContext(Expression expression, MarkupContext context) {
+ return new Expression(expression.getRoot(), addDefaultContext(expression.getOptions(), context));
+ }
+
+ private Map<String, ExpressionNode> addDefaultContext(Map<String, ExpressionNode> options, MarkupContext context) {
+ if (context == null || options.containsKey(Syntax.CONTEXT_OPTION)) {
+ return options;
+ }
+ HashMap<String, ExpressionNode> newOptions = new HashMap<String, ExpressionNode>(options);
+ newOptions.put(Syntax.CONTEXT_OPTION, new StringConstant(context.getName()));
+ return newOptions;
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Fragment.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Fragment.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Fragment.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Fragment.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+
+/**
+ * A segment in an interpolation.
+ */
+public interface Fragment {
+
+ boolean isString();
+ boolean isExpression();
+
+ Expression getExpression();
+ String getText();
+
+ /**
+ * A fragment which is an expression.
+ */
+ public static class Expr implements Fragment {
+
+ private Expression expression;
+
+ public Expr(Expression expression) {
+ this.expression = expression;
+ }
+
+ @Override
+ public Expression getExpression() {
+ return expression;
+ }
+
+ @Override
+ public String getText() {
+ throw new UnsupportedOperationException("Not a text fragment");
+ }
+
+ public boolean isString() {
+ return false;
+ }
+
+ public boolean isExpression() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "Expr{" +
+ "expression=" + expression +
+ '}';
+ }
+ }
+
+ /**
+ * A text fragment.
+ */
+ public static class Text implements Fragment {
+ private String text;
+
+ public Text(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String getText() {
+ return text;
+ }
+
+ public boolean isString() {
+ return true;
+ }
+
+ public boolean isExpression() {
+ return false;
+ }
+
+ @Override
+ public Expression getExpression() {
+ throw new UnsupportedOperationException("Not an expression fragment");
+ }
+
+ @Override
+ public String toString() {
+ return "Text{" +
+ "text='" + text + '\'' +
+ '}';
+ }
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Fragment.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Interpolation.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Interpolation.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Interpolation.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Interpolation.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.Expression;
+
+/**
+ * A sequence with alternating string fragments and Sightly expressions.
+ * These result from parsing HTML attributes or string nodes.
+ * For instance "Hello ${World}!" would result in 3 fragments:
+ * "Hello ", ${World} and "!"
+ */
+public class Interpolation {
+
+ //todo: this should be immutable to maintain the design consistent
+
+ private List<Fragment> fragments = new ArrayList<Fragment>();
+
+ public void addFragment(Fragment fragment) {
+ fragments.add(fragment);
+ }
+
+ public void addExpression(Expression expression) {
+ fragments.add(new Fragment.Expr(expression));
+ }
+
+ public void addText(String text) {
+ fragments.add(new Fragment.Text(text));
+ }
+
+ /**
+ * Get the number of fragments
+ * @return the number of fragments
+ */
+ public int size() {
+ return fragments.size();
+ }
+
+ /**
+ * Return the fragment with the specified index
+ * @param index - the index of the fragments. must be less than the size of the interpolation
+ * @return - the specified fragment
+ * @throws IndexOutOfBoundsException - if the index is negative or greater or equal than size
+ */
+ public Fragment getFragment(int index) {
+ return fragments.get(index);
+ }
+
+ public Iterable<Fragment> getFragments() {
+ return fragments;
+ }
+
+ @Override
+ public String toString() {
+ return "Interpolation{" +
+ "fragments=" + fragments +
+ '}';
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/Interpolation.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserException.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserException.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserException.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+/**
+ * Plugin runtime exception to be used for either html or expression parser exceptions.
+ */
+public class ParserException extends RuntimeException {
+
+ public ParserException() {
+ super();
+ }
+
+ public ParserException(String message) {
+ super(message);
+ }
+
+ public ParserException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+
+ public ParserException(Throwable throwable) {
+ super(throwable);
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserHelper.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserHelper.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserHelper.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+
+/**
+ * Helper utilities for the ANTLR parser
+ */
+public class ParserHelper {
+
+ public static String unEscape(String original) {
+ return original.replaceAll("\\\\\"", "\"").replaceAll("\\\\'", "'");
+ }
+
+ public static StringConstant createStringConstant(String original) {
+ String escaped = StringEscapeUtils.unescapeJava(original);
+ String trimmed = escaped.substring(1, escaped.length() - 1);
+ return new StringConstant(trimmed);
+ }
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ParserHelper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SightlyParserErrorListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SightlyParserErrorListener.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SightlyParserErrorListener.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SightlyParserErrorListener.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.Parser;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.apache.sling.scripting.sightly.impl.compiler.SightlyParsingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@code SightlyParserErrorListener} handles parsing error reporting by sending offending input to a logger.
+ */
+public class SightlyParserErrorListener extends BaseErrorListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SightlyParserErrorListener.class);
+
+ @Override
+ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
+ List<String> stack = ((Parser) recognizer).getRuleInvocationStack();
+ Collections.reverse(stack);
+ StringBuilder errorMessage = new StringBuilder();
+ errorMessage.append("Sightly syntax error detected.\n");
+ errorMessage.append("rule stack: ").append(stack).append("\n");
+ errorMessage.append("error starts at column: ").append(charPositionInLine).append("\n");
+ errorMessage.append(msg);
+ throw new SightlyParsingException("Sightly syntax error detected", ((CommonTokenStream) recognizer.getInputStream()).getTokenSource().getInputStream().toString(), e);
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SightlyParserErrorListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.frontend;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.CompilerFrontend;
+import org.apache.sling.scripting.sightly.impl.filter.Filter;
+import org.apache.sling.scripting.sightly.impl.html.dom.HtmlParserService;
+import org.apache.sling.scripting.sightly.impl.html.dom.MarkupHandler;
+import org.apache.sling.scripting.sightly.impl.plugin.Plugin;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+
+/**
+ * DOM-based compiler implementation
+ */
+public class SimpleFrontend implements CompilerFrontend {
+
+ private final HtmlParserService htmlParserService;
+ private final Map<String, Plugin> plugins;
+ private final List<Filter> filters;
+
+ public SimpleFrontend(HtmlParserService htmlParserService, Collection<Plugin> plugins, Collection<Filter> filters) {
+ this.plugins = new HashMap<String, Plugin>();
+ for (Plugin plugin : plugins) {
+ this.plugins.put(plugin.name(), plugin);
+ }
+ this.filters = new ArrayList<Filter>(filters);
+ this.htmlParserService = htmlParserService;
+ }
+
+ @Override
+ public void compile(PushStream stream, String source) {
+ MarkupHandler markupHandler = new MarkupHandler(stream, plugins, filters);
+ htmlParserService.parse(source, markupHandler);
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CoalescingWrites.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CoalescingWrites.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CoalescingWrites.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CoalescingWrites.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandHandler;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+
+/**
+ * Aggregate consecutive writes in bigger chunks of text
+ */
+public final class CoalescingWrites implements CommandHandler {
+
+ public static final StreamTransformer TRANSFORMER = new StreamTransformer() {
+ @Override
+ public CommandStream transform(CommandStream inStream) {
+ PushStream outputStream = new PushStream();
+ CoalescingWrites instance = new CoalescingWrites(outputStream);
+ inStream.addHandler(instance);
+ return outputStream;
+ }
+ };
+
+ private StringBuilder builder = new StringBuilder();
+ private final PushStream outStream;
+
+ private CoalescingWrites(PushStream stream) {
+ this.outStream = stream;
+ }
+
+ @Override
+ public void onEmit(Command command) {
+ String text = detectText(command);
+ if (text != null) {
+ builder.append(text);
+ } else {
+ flushText();
+ outStream.emit(command);
+ }
+ }
+
+
+ @Override
+ public void onError(String errorMessage) {
+ flushText();
+ outStream.signalError(errorMessage);
+ }
+
+ @Override
+ public void onDone() {
+ flushText();
+ outStream.signalDone();
+ }
+
+ private String detectText(Command command) {
+ if (command instanceof OutText) {
+ return ((OutText) command).getText();
+ }
+ return null;
+ }
+
+ private void flushText() {
+ if (builder.length() > 0) {
+ outStream.emit(new OutText(builder.toString()));
+ builder = new StringBuilder();
+ }
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CoalescingWrites.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CommandVariableUsage.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CommandVariableUsage.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CommandVariableUsage.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CommandVariableUsage.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Loop;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutText;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+
+/**
+ * Extracts the variables used in a command
+ */
+public class CommandVariableUsage implements CommandVisitor {
+
+ private ArrayList<String> variables = new ArrayList<String>();
+
+ public static List<String> extractVariables(Command command) {
+ CommandVariableUsage cvu = new CommandVariableUsage();
+ command.accept(cvu);
+ return cvu.variables;
+ }
+
+ @Override
+ public void visit(Conditional.Start conditionalStart) {
+ variables.add(conditionalStart.getVariable());
+ }
+
+ @Override
+ public void visit(Conditional.End conditionalEnd) {
+ }
+
+ @Override
+ public void visit(VariableBinding.Start variableBindingStart) {
+ addFromExpression(variableBindingStart.getExpression());
+ }
+
+ @Override
+ public void visit(VariableBinding.End variableBindingEnd) {
+ }
+
+ @Override
+ public void visit(VariableBinding.Global globalAssignment) {
+ addFromExpression(globalAssignment.getExpression());
+ }
+
+ private void addFromExpression(ExpressionNode node) {
+ variables.addAll(VariableFinder.findVariables(node));
+ }
+
+ @Override
+ public void visit(OutVariable outVariable) {
+ variables.add(outVariable.getVariableName());
+ }
+
+ @Override
+ public void visit(OutText outText) {
+ }
+
+ @Override
+ public void visit(Loop.Start loopStart) {
+ variables.add(loopStart.getListVariable());
+ }
+
+ @Override
+ public void visit(Loop.End loopEnd) {
+ }
+
+ @Override
+ public void visit(Procedure.Start startProcedure) {
+ }
+
+ @Override
+ public void visit(Procedure.End endProcedure) {
+ }
+
+ @Override
+ public void visit(Procedure.Call procedureCall) {
+ variables.add(procedureCall.getTemplateVariable());
+ variables.add(procedureCall.getArgumentsVariable());
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/CommandVariableUsage.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/DeadCodeRemoval.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/DeadCodeRemoval.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/DeadCodeRemoval.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/DeadCodeRemoval.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import java.util.Stack;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.EmitterVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.Streams;
+import org.apache.sling.scripting.sightly.impl.compiler.visitor.StatefulRangeIgnore;
+import org.apache.sling.scripting.sightly.impl.compiler.visitor.StatefulVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.visitor.TrackingVisitor;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+
+/**
+ * Removes code under conditionals which are proven to fail. It is probably
+ * a good idea to run this optimization after running
+ * {@link org.apache.sling.scripting.sightly.impl.compiler.optimization.reduce.ConstantFolding}
+ */
+public class DeadCodeRemoval extends TrackingVisitor<Boolean> implements EmitterVisitor {
+ // this could be merged with constant folding for better accuracy
+
+ public static StreamTransformer transformer(final RenderContext renderContext) {
+ return new StreamTransformer() {
+ @Override
+ public CommandStream transform(CommandStream inStream) {
+ StatefulVisitor visitor = new StatefulVisitor();
+ DeadCodeRemoval dcr = new DeadCodeRemoval(visitor.getControl(), renderContext);
+ visitor.initializeWith(dcr);
+ Streams.connect(inStream, dcr.getOutputStream(), visitor);
+ return dcr.getOutputStream();
+ }
+ };
+ }
+
+ private final PushStream outStream = new PushStream();
+ private final StatefulVisitor.StateControl stateControl;
+ private final RenderContext renderContext;
+ private final Stack<Boolean> keepConditionalEndStack = new Stack<Boolean>();
+
+ public DeadCodeRemoval(StatefulVisitor.StateControl stateControl, RenderContext renderContext) {
+ this.stateControl = stateControl;
+ this.renderContext = renderContext;
+ }
+
+ @Override
+ public void visit(VariableBinding.Start variableBindingStart) {
+ Boolean truthValue = decodeConstantBool(variableBindingStart.getExpression());
+ tracker.pushVariable(variableBindingStart.getVariableName(), truthValue);
+ outStream.emit(variableBindingStart);
+ }
+
+ @Override
+ public void visit(Conditional.Start conditionalStart) {
+ Boolean truthValue = tracker.get(conditionalStart.getVariable());
+ boolean keepConditionalEnd;
+ if (truthValue == null) { //no information about the value of this variable
+ keepConditionalEnd = true;
+ outStream.emit(conditionalStart);
+ } else { //we already know what happens with this conditional. We can remove it
+ keepConditionalEnd = false;
+ if (truthValue != conditionalStart.getExpectedTruthValue()) {
+ //this conditional will always fail. We can ignore everything until
+ //the corresponding end-conditional
+ stateControl.push(new StatefulRangeIgnore(stateControl, Conditional.Start.class, Conditional.End.class));
+ return;
+ }
+ }
+ keepConditionalEndStack.push(keepConditionalEnd);
+ }
+
+ @Override
+ public void visit(Conditional.End conditionalEnd) {
+ boolean keep = keepConditionalEndStack.pop();
+ if (keep) {
+ outStream.emit(conditionalEnd);
+ }
+ }
+
+ @Override
+ public PushStream getOutputStream() {
+ return outStream;
+ }
+
+ @Override
+ protected Boolean assignDefault(Command command) {
+ return null;
+ }
+
+ @Override
+ protected void onCommand(Command command) {
+ outStream.emit(command);
+ }
+
+ private Boolean decodeConstantBool(ExpressionNode node) {
+ if (node instanceof StringConstant) {
+ return renderContext.toBoolean(((StringConstant) node).getText());
+ }
+ if (node instanceof BooleanConstant) {
+ return ((BooleanConstant) node).getValue();
+ }
+ if (node instanceof NumericConstant) {
+ return renderContext.toBoolean(((NumericConstant) node).getValue());
+ }
+ if (node instanceof NullLiteral) {
+ return renderContext.toBoolean(null);
+ }
+ return null;
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/DeadCodeRemoval.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SequenceStreamTransformer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SequenceStreamTransformer.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SequenceStreamTransformer.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SequenceStreamTransformer.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+
+/**
+ * Applies a list of transformations in sequence
+ */
+public class SequenceStreamTransformer implements StreamTransformer {
+
+ private List<StreamTransformer> transformers;
+
+ public SequenceStreamTransformer(List<StreamTransformer> transformers) {
+ this.transformers = new ArrayList<StreamTransformer>(transformers);
+ }
+
+ @Override
+ public CommandStream transform(CommandStream inStream) {
+ CommandStream stream = inStream;
+ for (StreamTransformer transformer : transformers) {
+ stream = transformer.transform(stream);
+ }
+ return stream;
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SequenceStreamTransformer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/StreamTransformer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/StreamTransformer.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/StreamTransformer.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/StreamTransformer.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+
+/**
+ * Interface for stream transformations
+ */
+public interface StreamTransformer {
+
+ /**
+ * Given the input stream, return a transformed out stream
+ * @param inStream the input stream
+ * @return the result stream
+ */
+ CommandStream transform(CommandStream inStream);
+
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/StreamTransformer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SyntheticMapRemoval.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SyntheticMapRemoval.java?rev=1642281&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SyntheticMapRemoval.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SyntheticMapRemoval.java Fri Nov 28 10:18:01 2014
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * 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 org.apache.sling.scripting.sightly.impl.compiler.optimization;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.impl.compiler.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.Command;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.CommandStream;
+import org.apache.sling.scripting.sightly.impl.compiler.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.impl.compiler.util.expression.NodeTransformer;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.EmitterVisitor;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.util.stream.Streams;
+import org.apache.sling.scripting.sightly.impl.compiler.visitor.TrackingVisitor;
+
+/**
+ * This optimization handles variables initialized to map literals. It
+ * initially assigns the values in the map to variables and wherever
+ * the map literal is accessed, the property access is replaced with
+ * the value variable, thus removing the need for a map lookup.
+ */
+public final class SyntheticMapRemoval extends TrackingVisitor<MapLiteral> implements EmitterVisitor {
+
+ public static final StreamTransformer TRANSFORMER = new StreamTransformer() {
+ @Override
+ public CommandStream transform(CommandStream inStream) {
+ return Streams.map(inStream, new SyntheticMapRemoval());
+ }
+ };
+
+ private static final String VARIABLE_MARKER = "_field$_";
+
+ private final PushStream outputStream = new PushStream();
+ private final NodeTransformer transformer = new PropertyAccessTransformer();
+
+ private SyntheticMapRemoval() {
+ }
+
+ @Override
+ public void visit(VariableBinding.Start variableBindingStart) {
+ ExpressionNode node = variableBindingStart.getExpression();
+ String variable = variableBindingStart.getVariableName();
+ ExpressionNode transformed = transform(node);
+ if (transformed instanceof MapLiteral) {
+ MapLiteral newLiteral = overrideMap(variable, (MapLiteral) transformed);
+ tracker.pushVariable(variable, newLiteral);
+ transformed = newLiteral;
+ } else {
+ tracker.pushVariable(variable, null);
+ }
+ outputStream.emit(new VariableBinding.Start(variable, transformed));
+ }
+
+ @Override
+ public void visit(VariableBinding.End variableBindingEnd) {
+ Map.Entry<String, MapLiteral> entry = tracker.peek();
+ super.visit(variableBindingEnd);
+ MapLiteral literal = entry.getValue();
+ if (literal != null) {
+ //need to un-bind all the introduced variables
+ for (int i = 0; i < literal.getMap().size(); i++) {
+ outputStream.emit(VariableBinding.END);
+ }
+ }
+ }
+
+ private ExpressionNode transform(ExpressionNode node) {
+ return transformer.transform(node);
+ }
+
+ private MapLiteral overrideMap(String variableName, MapLiteral mapLiteral) {
+ Map<String, ExpressionNode> newLiteral = new HashMap<String, ExpressionNode>();
+ for (Map.Entry<String, ExpressionNode> entry : mapLiteral.getMap().entrySet()) {
+ String property = entry.getKey();
+ ExpressionNode valueNode = entry.getValue();
+ String valueVariable = valueVariableName(variableName, property);
+ newLiteral.put(property, new Identifier(valueVariable));
+ outputStream.emit(new VariableBinding.Start(valueVariable, valueNode));
+ }
+ return new MapLiteral(newLiteral);
+ }
+
+ private String valueVariableName(String variableName, String propertyName) {
+ return variableName + VARIABLE_MARKER + propertyName;
+ }
+
+ @Override
+ protected MapLiteral assignDefault(Command command) {
+ return null;
+ }
+
+ @Override
+ public void onCommand(Command command) {
+ outputStream.emit(command);
+ }
+
+ @Override
+ public PushStream getOutputStream() {
+ return outputStream;
+ }
+
+ private class PropertyAccessTransformer extends NodeTransformer {
+ @Override
+ public ExpressionNode evaluate(PropertyAccess propertyAccess) {
+ ExpressionNode target = propertyAccess.getTarget();
+ String variable = extractIdentifier(target);
+ if (variable != null) {
+ MapLiteral literal = tracker.get(variable);
+ if (literal != null) {
+ String property = extractProperty(propertyAccess.getProperty());
+ if (property != null) {
+ ExpressionNode replacementNode = literal.getValue(property);
+ if (replacementNode == null) {
+ replacementNode = NullLiteral.INSTANCE;
+ }
+ return replacementNode;
+ }
+ }
+ }
+ return super.evaluate(propertyAccess);
+ }
+
+ private String extractProperty(ExpressionNode expressionNode) {
+ if (expressionNode instanceof StringConstant) {
+ return ((StringConstant) expressionNode).getText();
+ }
+ return null;
+ }
+
+ private String extractIdentifier(ExpressionNode node) {
+ if (node instanceof Identifier) {
+ return ((Identifier) node).getName();
+ }
+ return null;
+ }
+ }
+}
Propchange: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/SyntheticMapRemoval.java
------------------------------------------------------------------------------
svn:mime-type = text/plain