You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2014/11/14 15:05:03 UTC
svn commit: r1639641 [3/15] - in /sling/trunk/contrib/scripting/sightly: ./
engine/ engine/src/ engine/src/main/ engine/src/main/antlr4/
engine/src/main/antlr4/org/ engine/src/main/antlr4/org/apache/
engine/src/main/antlr4/org/apache/sling/ engine/src/...
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CodeGenVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CodeGenVisitor.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CodeGenVisitor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CodeGenVisitor.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.compiler.api.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.BufferControl;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Conditional;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Loop;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutText;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutVariable;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.Procedure;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.VariableBinding;
+import org.apache.sling.scripting.sightly.compiler.visitor.StateControl;
+import org.apache.sling.scripting.sightly.compiler.api.ris.CommandVisitor;
+import org.apache.sling.scripting.sightly.compiler.api.ris.command.OutText;
+import org.apache.sling.scripting.sightly.compiler.visitor.StateControl;
+
+/**
+ * Java code generator
+ */
+class CodeGenVisitor implements CommandVisitor {
+
+ private final JavaSource source;
+ private final UnitBuilder unitBuilder;
+ private final Stack<String> loopStatusStack = new Stack<String>();
+ private final VariableAnalyzer analyzer = new VariableAnalyzer();
+ private final StateControl control;
+ private final Set<String> unitParameters;
+
+ public CodeGenVisitor(UnitBuilder unitBuilder, StateControl control) {
+ this.unitBuilder = unitBuilder;
+ this.source = unitBuilder.getSource();
+ this.control = control;
+ this.unitParameters = new HashSet<String>();
+ for (String param : unitBuilder.getParameters()) {
+ this.unitParameters.add(param.toLowerCase());
+ }
+ }
+
+ /**
+ * Complete building the source
+ */
+ public void finish() {
+ source.prepend(initializations());
+ }
+
+ private String initializations() {
+ JavaSource initSource = new JavaSource();
+ for (VariableDescriptor descriptor : analyzer.allVariables()) {
+ initVariable(descriptor, initSource);
+ }
+ return initSource.toString();
+ }
+
+ private void initVariable(VariableDescriptor descriptor, JavaSource initSource) {
+ switch (descriptor.getScope()) {
+ case DYNAMIC:
+ initSource.beginAssignment(descriptor.getAssignedName());
+ if (descriptor.isTemplateVariable()) {
+ initSource.startCall(SourceGenConstants.OBJ_GET);
+ } else if (unitParameters.contains(descriptor.getOriginalName().toLowerCase())) {
+ initSource.startMethodCall(SourceGenConstants.ARGUMENTS_FIELD, SourceGenConstants.BINDINGS_GET_METHOD);
+ } else {
+ initSource.startMethodCall(SourceGenConstants.BINDINGS_FIELD, SourceGenConstants.BINDINGS_GET_METHOD);
+ }
+ initSource.stringLiteral(descriptor.getOriginalName())
+ .endCall()
+ .endStatement();
+ break;
+ case GLOBAL:
+ initSource.beginAssignment(descriptor.getAssignedName())
+ .nullLiteral()
+ .endStatement();
+ break;
+ }
+ String listCoercionVar = descriptor.getListCoercion();
+ if (listCoercionVar != null) {
+ //need to initialize the list coercion to null
+ initSource.beginAssignment(listCoercionVar, SourceGenConstants.COLLECTION_TYPE)
+ .nullLiteral().endStatement();
+ }
+ }
+
+ @Override
+ public void visit(Conditional.Start conditional) {
+ VariableDescriptor descriptor = analyzer.descriptor(conditional.getVariable());
+ boolean negate = !conditional.getExpectedTruthValue();
+ source.beginIf();
+ if (negate) {
+ source.negation();
+ }
+ if (descriptor.getType() == Type.BOOLEAN) {
+ source.append(descriptor.getAssignedName());
+ } else {
+ source.startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, ObjectModel.BOOLEAN_COERCE)
+ .append(descriptor.getAssignedName())
+ .endCall();
+ }
+ source.completeIf();
+ }
+
+ @Override
+ public void visit(Conditional.End conditionalEnd) {
+ source.endIf();
+ }
+
+ @Override
+ public void visit(VariableBinding.Start variableBinding) {
+ source.startBlock();
+ TypeInfo typeInfo = TypeInference.inferTypes(variableBinding.getExpression(), analyzer);
+ Type type = typeInfo.typeOf(variableBinding.getExpression());
+ String properName = declare(variableBinding.getVariableName(), type);
+ source.beginAssignment(properName, type.getNativeClass());
+ ExpressionTranslator.buildExpression(
+ variableBinding.getExpression(),
+ source,
+ analyzer,
+ typeInfo);
+ source.endStatement();
+ }
+
+ @Override
+ public void visit(VariableBinding.End variableBindingEnd) {
+ VariableDescriptor descriptor = analyzer.endVariable();
+ String listCoercionVar = descriptor.getListCoercion();
+ if (listCoercionVar != null) {
+ //this variable was coerced to list at some point
+ generateCoercionClearing(listCoercionVar);
+ }
+ source.endBlock();
+ }
+
+ @Override
+ public void visit(VariableBinding.Global globalAssignment) {
+ TypeInfo typeInfo = TypeInference.inferTypes(globalAssignment.getExpression(), analyzer);
+ VariableDescriptor descriptor = analyzer.declareGlobal(globalAssignment.getVariableName());
+ String name = descriptor.getAssignedName();
+ source.append(name).assign();
+ ExpressionTranslator.buildExpression(
+ globalAssignment.getExpression(),
+ source,
+ analyzer,
+ typeInfo);
+ source.endStatement();
+ String listCoercionVar = descriptor.getListCoercion();
+ if (listCoercionVar != null) {
+ //variable was used for list coercion. Generating a coercion clearing
+ generateCoercionClearing(listCoercionVar);
+ }
+ }
+
+ @Override
+ public void visit(OutVariable outVariable) {
+ String variable = analyzer.assignedName(outVariable.getVariableName());
+ source.startStatement()
+ .startMethodCall(SourceGenConstants.OUT_BUFFER, SourceGenConstants.WRITE_METHOD)
+ .startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, ObjectModel.STRING_COERCE)
+ .append(variable)
+ .endCall()
+ .endCall()
+ .endStatement();
+ }
+
+ @Override
+ public void visit(OutText outText) {
+ source.startStatement()
+ .startMethodCall(SourceGenConstants.OUT_BUFFER, SourceGenConstants.WRITE_METHOD)
+ .stringLiteral(outText.getText())
+ .endCall()
+ .endStatement();
+ }
+
+ @Override
+ public void visit(Loop.Start loop) {
+ VariableDescriptor descriptor = analyzer.descriptor(loop.getListVariable());
+ String listVariable = descriptor.getAssignedName();
+ String collectionVar = descriptor.requireListCoercion();
+ source.beginIf().append(collectionVar).equality().nullLiteral().completeIf()
+ .startStatement()
+ .append(collectionVar)
+ .assign()
+ .startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, ObjectModel.COLLECTION_COERCE)
+ .append(listVariable)
+ .endCall()
+ .endStatement()
+ .endIf();
+ String indexVar = declare(loop.getIndexVariable(), Type.LONG);
+ source.beginAssignment(indexVar, Type.LONG.getNativeClass()).number(0).endStatement();
+ String itemVar = declare(loop.getItemVariable(), Type.UNKNOWN);
+ source.beginFor(itemVar, collectionVar);
+ loopStatusStack.push(indexVar);
+ }
+
+ @Override
+ public void visit(Loop.End loopEnd) {
+ String indexVar = loopStatusStack.pop();
+ source.startStatement().append(indexVar).increment().endStatement();
+ source.endFor();
+ analyzer.endVariable();
+ analyzer.endVariable();
+ }
+
+ @Override
+ public void visit(BufferControl.Push bufferPush) {
+ source.startStatement()
+ .startMethodCall(SourceGenConstants.OUT_BUFFER, SourceGenConstants.PUSH_BUFFER_METHOD)
+ .endCall()
+ .endStatement();
+ }
+
+ @Override
+ public void visit(BufferControl.Pop bufferPop) {
+ source.startBlock();
+ String outputVar = declare(bufferPop.getVariableName(), Type.STRING);
+ source.beginAssignment(outputVar, Type.STRING.getNativeClass())
+ .startMethodCall(SourceGenConstants.OUT_BUFFER, SourceGenConstants.POP_BUFFER_METHOD)
+ .endCall()
+ .endStatement();
+ }
+
+ @Override
+ public void visit(Procedure.Start startProcedure) {
+ UnitBuilder subTemplateUnit = unitBuilder.newSubBuilder(startProcedure.getName(), startProcedure.getParameters());
+ analyzer.declareTemplate(startProcedure.getName());
+ control.push(new CodeGenVisitor(subTemplateUnit, control));
+ }
+
+ @Override
+ public void visit(Procedure.End endProcedure) {
+ CodeGenVisitor previous = (CodeGenVisitor) control.pop();
+ previous.finish();
+ }
+
+ @Override
+ public void visit(Procedure.Call procedureCall) {
+ String templateVar = analyzer.assignedName(procedureCall.getTemplateVariable());
+ String argVar = analyzer.assignedName(procedureCall.getArgumentsVariable());
+ source.startStatement()
+ .startCall(SourceGenConstants.CALL_UNIT_METHOD, false)
+ .append(SourceGenConstants.RENDER_CONTEXT_INSTANCE)
+ .separateArgument()
+ .append(templateVar)
+ .separateArgument()
+ .append(argVar)
+ .endCall()
+ .endStatement();
+ }
+
+ private String declare(String originalName, Type type) {
+ return analyzer.declareVariable(originalName, type).getAssignedName();
+ }
+
+ private void generateCoercionClearing(String coercionVariableName) {
+ source.startStatement().append(coercionVariableName).assign().nullLiteral().endStatement();
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CompilationOutput.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CompilationOutput.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CompilationOutput.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/CompilationOutput.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.Map;
+
+/**
+ * Result from compilation
+ */
+public class CompilationOutput {
+
+ private final String mainBody;
+ private final Map<String, CompilationOutput> subTemplates;
+
+ public CompilationOutput(String mainBody, Map<String, CompilationOutput> subTemplates) {
+ this.mainBody = mainBody;
+ this.subTemplates = subTemplates;
+ }
+
+ public String getMainBody() {
+ return mainBody;
+ }
+
+ public Map<String, CompilationOutput> getSubTemplates() {
+ return subTemplates;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/ExpressionTranslator.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/ExpressionTranslator.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/ExpressionTranslator.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/ExpressionTranslator.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.compiled.operator.BinaryOpGen;
+import org.apache.sling.scripting.sightly.compiled.operator.Operators;
+import org.apache.sling.scripting.sightly.compiled.operator.UnaryOpGen;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.ArrayLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.TernaryOperator;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.UnaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.UnaryOperator;
+import org.apache.sling.scripting.sightly.compiler.util.expression.SideEffectVisitor;
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.compiled.operator.BinaryOpGen;
+import org.apache.sling.scripting.sightly.compiled.operator.Operators;
+import org.apache.sling.scripting.sightly.compiled.operator.UnaryOpGen;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.*;
+import org.apache.sling.scripting.sightly.compiler.util.expression.SideEffectVisitor;
+
+
+/**
+ * Builds expressions within a sling source file.
+ */
+public final class ExpressionTranslator extends SideEffectVisitor {
+
+ private final JavaSource source;
+ private final VariableAnalyzer analyzer;
+ private final TypeInfo typeInfo;
+
+ private ExpressionTranslator(JavaSource source, VariableAnalyzer analyzer, TypeInfo typeInfo) {
+ this.source = source;
+ this.analyzer = analyzer;
+ this.typeInfo= typeInfo;
+ }
+
+ public static void buildExpression(ExpressionNode node,
+ JavaSource source,
+ VariableAnalyzer analyzer,
+ TypeInfo typeInfo) {
+ ExpressionTranslator builder = new ExpressionTranslator(source, analyzer, typeInfo);
+ builder.traverse(node);
+ }
+
+ public void traverse(ExpressionNode node) {
+ visit(node);
+ }
+
+ private void visit(ExpressionNode node) {
+ node.accept(this);
+ }
+
+ @Override
+ public void visit(PropertyAccess propertyAccess) {
+ if (typeInfo.typeOf(propertyAccess.getTarget()) == Type.MAP) {
+ //Special optimization for maps
+ visit(propertyAccess.getTarget());
+ source.startCall(SourceGenConstants.MAP_GET, true);
+ visit(propertyAccess.getProperty());
+ source.endCall();
+ } else {
+ source.startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, ObjectModel.PROPERTY_ACCESS);
+ visit(propertyAccess.getTarget());
+ source.separateArgument();
+ visit(propertyAccess.getProperty());
+ source.endCall();
+ }
+ }
+
+ @Override
+ public void visit(Identifier identifier) {
+ String safeName = analyzer.assignedName(identifier.getName());
+ source.append(safeName);
+ }
+
+ @Override
+ public void visit(StringConstant text) {
+ source.stringLiteral(text.getText());
+ }
+
+ @Override
+ public void visit(BinaryOperation binaryOperation) {
+ BinaryOpGen opGen = Operators.generatorFor(binaryOperation.getOperator());
+ source.startExpression();
+ opGen.generate(source, this,
+ typeInfo.getTyped(binaryOperation.getLeftOperand()),
+ typeInfo.getTyped(binaryOperation.getRightOperand()));
+ source.endExpression();
+ }
+
+ @Override
+ public void visit(BooleanConstant booleanConstant) {
+ source.append(Boolean.toString(booleanConstant.getValue()));
+ }
+
+ @Override
+ public void visit(NumericConstant numericConstant) {
+ source.append(numericConstant.getValue().toString()); //todo: check correctness
+ }
+
+ @Override
+ public void visit(UnaryOperation unaryOperation) {
+ UnaryOperator operator = unaryOperation.getOperator();
+ ExpressionNode operand = unaryOperation.getTarget();
+ UnaryOpGen unaryOpGen = Operators.generatorFor(operator);
+ source.startExpression();
+ unaryOpGen.generate(source, this, typeInfo.getTyped(operand));
+ source.endExpression();
+ }
+
+ @Override
+ public void visit(TernaryOperator ternaryOperator) {
+ GenHelper.generateTernary(source, this,
+ typeInfo.getTyped(ternaryOperator.getCondition()),
+ typeInfo.getTyped(ternaryOperator.getThenBranch()),
+ typeInfo.getTyped(ternaryOperator.getElseBranch()));
+ }
+
+ @Override
+ public void visit(RuntimeCall runtimeCall) {
+ source.startMethodCall(SourceGenConstants.RUNTIME_INSTANCE, SourceGenConstants.RUNTIME_CALL_METHOD)
+ .stringLiteral(runtimeCall.getFunctionName());
+ for (ExpressionNode arg : runtimeCall.getArguments()) {
+ source.separateArgument();
+ visit(arg);
+ }
+ source.endCall();
+ }
+
+ @Override
+ public void visit(MapLiteral mapLiteral) {
+ source.startCall(SourceGenConstants.START_MAP_METHOD).endCall();
+ for (Map.Entry<String, ExpressionNode> entry : mapLiteral.getMap().entrySet()) {
+ source.startCall(SourceGenConstants.MAP_TYPE_ADD, true)
+ .stringLiteral(entry.getKey())
+ .separateArgument();
+ visit(entry.getValue());
+ source.endCall();
+ }
+ }
+
+ @Override
+ public void visit(ArrayLiteral arrayLiteral) {
+ source.startExpression().startArray();
+ boolean needsComma = false;
+ for (ExpressionNode node : arrayLiteral.getItems()) {
+ if (needsComma) {
+ source.separateArgument();
+ }
+ visit(node);
+ needsComma = true;
+ }
+ source.endArray().endExpression();
+ }
+
+ @Override
+ public void visit(NullLiteral nullLiteral) {
+ source.nullLiteral();
+ }
+
+ public VariableAnalyzer getAnalyzer() {
+ return analyzer;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/GenHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/GenHelper.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/GenHelper.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/GenHelper.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.compiled.operator.TypedNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.util.expression.SideEffectVisitor;
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.compiled.operator.TypedNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.util.expression.SideEffectVisitor;
+
+/**
+ * Helper for code generation
+ */
+public class GenHelper {
+
+ public static void generateTernary(JavaSource source, SideEffectVisitor visitor,
+ TypedNode condition, TypedNode thenBranch, TypedNode elseBranch) {
+ source.startExpression();
+ typeCoercion(source, visitor, condition, Type.BOOLEAN);
+ source.conditional();
+ thenBranch.getNode().accept(visitor);
+ source.conditionalBranchSep();
+ elseBranch.getNode().accept(visitor);
+ source.endExpression();
+ }
+
+ public static void typeCoercion(JavaSource source, SideEffectVisitor visitor, TypedNode node, Type type) {
+ if (type == node.getType() || type == Type.UNKNOWN) {
+ node.getNode().accept(visitor);
+ } else if (type == Type.LONG && node.getType() == Type.DOUBLE) {
+ callLongCoercion(source, visitor, node.getNode());
+ } else {
+ String coercionMethod = dynamicCoercions.get(type);
+ if (coercionMethod == null) {
+ throw new UnsupportedOperationException("Cannot generate coercion to type " + type);
+ }
+ callDynamicCoercion(source, visitor, node.getNode(), dynamicCoercions.get(type));
+ }
+ }
+
+ public static void listCoercion(JavaSource source, ExpressionTranslator visitor, TypedNode typedNode) {
+ ExpressionNode node = typedNode.getNode();
+ if (node instanceof Identifier) {
+ //using list coercion caching optimization
+ VariableDescriptor descriptor = visitor.getAnalyzer().descriptor(((Identifier) node).getName());
+ String listCoercionVar = descriptor.requireListCoercion();
+ source.startExpression()
+ .append(listCoercionVar)
+ .equality()
+ .nullLiteral()
+ .conditional()
+ .startExpression()
+ .append(listCoercionVar)
+ .assign()
+ .startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, ObjectModel.COLLECTION_COERCE);
+ node.accept(visitor);
+ source
+ .endCall()
+ .endExpression()
+ .conditionalBranchSep()
+ .append(listCoercionVar)
+ .endExpression();
+ } else {
+ source.startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, ObjectModel.COLLECTION_COERCE);
+ typedNode.getNode().accept(visitor);
+ source.endCall();
+ }
+ }
+
+ private static void callLongCoercion(JavaSource source, SideEffectVisitor visitor, ExpressionNode node) {
+ source.cast(Type.LONG.getNativeClass());
+ source.startExpression();
+ node.accept(visitor);
+ source.endExpression();
+ }
+
+ private static void callDynamicCoercion(JavaSource source, SideEffectVisitor visitor, ExpressionNode node, String methodName) {
+ source.startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, methodName);
+ node.accept(visitor);
+ source.endCall();
+ }
+
+ private static final Map<Type, String> dynamicCoercions = new HashMap<Type, String>();
+
+ static {
+ dynamicCoercions.put(Type.STRING, ObjectModel.STRING_COERCE);
+ dynamicCoercions.put(Type.BOOLEAN, ObjectModel.BOOLEAN_COERCE);
+ dynamicCoercions.put(Type.LONG, ObjectModel.NUMERIC_COERCE);
+ dynamicCoercions.put(Type.DOUBLE, ObjectModel.NUMERIC_COERCE);
+ }
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaClassBackend.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaClassBackend.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaClassBackend.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaClassBackend.java Fri Nov 14 14:04:56 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.compiled;
+
+import org.apache.sling.scripting.sightly.compiler.CompilerBackend;
+import org.apache.sling.scripting.sightly.compiler.api.ris.CommandStream;
+import org.apache.sling.scripting.sightly.compiler.util.stream.VisitorHandler;
+import org.apache.sling.scripting.sightly.compiler.visitor.StatefulVisitor;
+import org.apache.sling.scripting.sightly.compiler.visitor.StatefulVisitor;
+
+/**
+ * Backend which generates a Java class.
+ */
+public class JavaClassBackend implements CompilerBackend {
+
+ private UnitBuilder unitBuilder = new UnitBuilder();
+
+ @Override
+ public void handle(CommandStream stream) {
+ StatefulVisitor statefulVisitor = new StatefulVisitor();
+ final CodeGenVisitor visitor = new CodeGenVisitor(unitBuilder, statefulVisitor.getControl());
+ statefulVisitor.initializeWith(visitor);
+ stream.addHandler(new VisitorHandler(statefulVisitor) {
+ @Override
+ public void onDone() {
+ super.onDone();
+ visitor.finish();
+ }
+ });
+ }
+
+ public CompilationOutput build() {
+ return this.unitBuilder.build();
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaSource.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaSource.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaSource.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/JavaSource.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+/**
+ * Builder object for a Java class printing method.
+ */
+public class JavaSource {
+
+ private static final String INDENT = " ";
+
+ private int indentLevel;
+ private final StringBuilder builder = new StringBuilder();
+
+ public JavaSource prepend(String str) {
+ builder.insert(0, str);
+ return this;
+ }
+
+ public JavaSource beginIf() {
+ indent().append("if (");
+ return this;
+ }
+
+ public JavaSource completeIf() {
+ append(") {\n");
+ incIndent();
+ return this;
+ }
+
+ public JavaSource endBlock() {
+ decIndent();
+ indent().append("}\n");
+ return this;
+ }
+
+ public JavaSource comment(String text) {
+ indent().append("//").append(text).append("\n");
+ return this;
+ }
+
+ public JavaSource assign() {
+ return append(" = ");
+ }
+
+ public JavaSource number(int value) {
+ return append(Integer.toString(value));
+ }
+
+ public JavaSource increment() {
+ return append("++");
+ }
+
+ public JavaSource beginAssignment(String variable, String type) {
+ return declare(variable, type).assign();
+ }
+
+ public JavaSource beginAssignment(String variable) {
+ return beginAssignment(variable, "Object");
+ }
+
+ public JavaSource declare(String variable, String type) {
+ return startStatement().append(type).append(" ").append(variable);
+ }
+
+ public JavaSource declare(String variable) {
+ return declare(variable, "Object");
+ }
+
+ public JavaSource equality() {
+ return append(" == ");
+ }
+
+ public JavaSource startCall(String methodName, boolean useDot) {
+ if (useDot) {
+ builder.append('.');
+ }
+ builder.append(methodName).append('(');
+ return this;
+ }
+
+ public JavaSource startCall(String methodName) {
+ return startCall(methodName, false);
+ }
+
+ public JavaSource startMethodCall(String target, String method) {
+ return append(target).startCall(method, true);
+ }
+
+ public JavaSource startArray() {
+ return append("new Object[] {");
+ }
+
+ public JavaSource endArray() {
+ return append("}");
+ }
+
+ public JavaSource startStatement() {
+ indent();
+ return this;
+ }
+
+ public JavaSource nullLiteral() {
+ return append("null");
+ }
+
+ public JavaSource separateArgument() {
+ builder.append(", ");
+ return this;
+ }
+
+ public JavaSource stringLiteral(String text) {
+ builder.append('"')
+ .append(StringEscapeUtils.escapeJava(text))
+ .append('"');
+ return this;
+ }
+
+ public JavaSource startExpression() {
+ builder.append('(');
+ return this;
+ }
+
+ public JavaSource endExpression() {
+ builder.append(')');
+ return this;
+ }
+
+ public JavaSource endCall() {
+ builder.append(')');
+ return this;
+ }
+
+ public JavaSource startBlock() {
+ indent().append("{\n");
+ incIndent();
+ return this;
+ }
+
+ public JavaSource beginFor(String itemVariable, String listVariable) {
+ startStatement()
+ .append("for (Object ")
+ .append(itemVariable)
+ .append(" : ")
+ .append(listVariable)
+ .append(") {\n");
+ incIndent();
+ return this;
+ }
+
+ public JavaSource endFor() {
+ return endBlock();
+ }
+
+ public JavaSource endIf() {
+ return endBlock();
+ }
+
+ public JavaSource beginNewInstanceCall(String className) {
+ return append("new ").append(className).append("(");
+ }
+
+ public JavaSource append(String str) {
+ builder.append(str);
+ return this;
+ }
+
+ public JavaSource endStatement() {
+ builder.append(";\n");
+ return this;
+ }
+
+ public JavaSource cast(String type) {
+ return append("(").append(type).append(")");
+ }
+
+ public JavaSource operator(String op) {
+ return append(" ").append(op).append(" ");
+ }
+
+ public JavaSource beginAnonymousInstance(String className) {
+ append("new ").append(className).append("() {\n");
+ incIndent();
+ return this;
+ }
+
+ public JavaSource endAnonymousInstance() {
+ decIndent();
+ append("}");
+ return this;
+ }
+
+ public JavaSource beginMethod(String name, String returnType) {
+ return startStatement().append("public ").append(returnType).append(" ").append(name).append("(");
+ }
+
+ public JavaSource methodParameter(String name, String type) {
+ return append(type).append(" ").append(name);
+ }
+
+ public JavaSource completeMethodSignature() {
+ append(") {\n");
+ incIndent();
+ return this;
+ }
+
+ public JavaSource endMethod() {
+ return endBlock();
+ }
+
+ public JavaSource conditional() {
+ return append(" ? ");
+ }
+
+ public JavaSource conditionalBranchSep() {
+ return append(" : ");
+ }
+
+ public JavaSource negation() {
+ return append("!");
+ }
+
+ public JavaSource newLine() {
+ return append("\n");
+ }
+
+ private StringBuilder indent() {
+ for (int i = 0; i < indentLevel; i++) {
+ builder.append(INDENT);
+ }
+ return builder;
+ }
+
+ private void incIndent() {
+ indentLevel++;
+ }
+
+ private void decIndent() {
+ indentLevel--;
+ }
+
+ @Override
+ public String toString() {
+ return builder.toString();
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/SourceGenConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/SourceGenConstants.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/SourceGenConstants.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/SourceGenConstants.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.compiled;
+
+/**
+ * Names related to Java source generation.
+ */
+public class SourceGenConstants {
+
+ public static final String OUT_BUFFER = "out";
+
+ public static final String WRITE_METHOD = "write";
+
+ public static final String COLLECTION_TYPE = "Collection";
+
+ public static final String BINDINGS_FIELD = "bindings";
+
+ public static final String BINDINGS_GET_METHOD = "get";
+
+ public static final String PUSH_BUFFER_METHOD = "push";
+
+ public static final String POP_BUFFER_METHOD = "pop";
+
+ public static final String START_MAP_METHOD = "obj";
+
+ public static final String MAP_TYPE_ADD = "with";
+
+ public static final String CALL_UNIT_METHOD = "callUnit";
+
+ public static final String RENDER_CONTEXT_INSTANCE = "renderContext";
+
+ public static final String OBJ_MODEL_INSTANCE = "objectModel";
+
+ public static final String RUNTIME_INSTANCE = "runtime";
+
+ public static final String RUNTIME_CALL_METHOD = "call";
+
+ public static final String COLLECTION_LENGTH_METHOD = "size";
+
+ public static final String MAP_GET = "get";
+ public static final String TRIM_METHOD = "trim";
+ public static final String STRING_EMPTY = "isEmpty";
+ public static final String OBJ_GET = "get";
+ public static final String ARGUMENTS_FIELD = "arguments";
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/Type.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/Type.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/Type.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/Type.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.compiled;
+
+/**
+ * Type inferred for an expression
+ */
+public enum Type {
+ UNKNOWN("Object", false),
+ STRING("String", false),
+ LONG("long", true),
+ DOUBLE("double", true),
+ BOOLEAN("boolean", true),
+ MAP("java.util.Map", false);
+
+ private final String nativeClass;
+ private final boolean isPrimitive;
+
+ Type(String nativeClass, boolean isPrimitive) {
+ this.nativeClass = nativeClass;
+ this.isPrimitive = isPrimitive;
+ }
+
+ public String getNativeClass() {
+ return nativeClass;
+ }
+
+ public boolean isPrimitive() {
+ return isPrimitive;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInference.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInference.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInference.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInference.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.compiled.operator.BinaryOpGen;
+import org.apache.sling.scripting.sightly.compiled.operator.Operators;
+import org.apache.sling.scripting.sightly.compiled.operator.UnaryOpGen;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.NodeVisitor;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.ArrayLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BooleanConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.Identifier;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.MapLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.NullLiteral;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.NumericConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.PropertyAccess;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.RuntimeCall;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.StringConstant;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.TernaryOperator;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.UnaryOperation;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.UnaryOperation;
+
+/**
+ * Expression translator which uses type information
+ */
+public final class TypeInference implements NodeVisitor<Type> {
+
+ private final VariableAnalyzer analyzer;
+ private final Map<ExpressionNode, Type> inferMap = new IdentityHashMap<ExpressionNode, Type>();
+
+
+ public static TypeInfo inferTypes(ExpressionNode node, VariableAnalyzer analyzer) {
+ TypeInference typeInference = new TypeInference(analyzer);
+ typeInference.infer(node);
+ return new TypeInfo(typeInference.inferMap);
+ }
+
+ private TypeInference(VariableAnalyzer analyzer) {
+ this.analyzer = analyzer;
+ }
+
+
+
+ private Type infer(ExpressionNode node) {
+ Type type = node.accept(this);
+ inferMap.put(node, type);
+ return type;
+ }
+
+ @Override
+ public Type evaluate(PropertyAccess propertyAccess) {
+ infer(propertyAccess.getTarget());
+ infer(propertyAccess.getProperty());
+ return Type.UNKNOWN;
+ }
+
+ @Override
+ public Type evaluate(Identifier identifier) {
+ return analyzer.descriptor(identifier.getName()).getType();
+ }
+
+ @Override
+ public Type evaluate(StringConstant text) {
+ return Type.STRING;
+ }
+
+ @Override
+ public Type evaluate(BinaryOperation binaryOperation) {
+ Type leftType = infer(binaryOperation.getLeftOperand());
+ Type rightType = infer(binaryOperation.getRightOperand());
+ BinaryOpGen opGen = Operators.generatorFor(binaryOperation.getOperator());
+ return opGen.returnType(leftType, rightType);
+ }
+
+ @Override
+ public Type evaluate(BooleanConstant booleanConstant) {
+ return Type.BOOLEAN;
+ }
+
+ @Override
+ public Type evaluate(NumericConstant numericConstant) {
+ Number number = numericConstant.getValue();
+ if (number instanceof Integer || number instanceof Long) {
+ return Type.LONG;
+ }
+ if (number instanceof Float || number instanceof Double) {
+ return Type.DOUBLE;
+ }
+ return Type.UNKNOWN;
+ }
+
+ @Override
+ public Type evaluate(UnaryOperation unaryOperation) {
+ infer(unaryOperation.getTarget());
+ UnaryOpGen opGen = Operators.generatorFor(unaryOperation.getOperator());
+ return opGen.returnType(infer(unaryOperation.getTarget()));
+ }
+
+ @Override
+ public Type evaluate(TernaryOperator ternaryOperator) {
+ infer(ternaryOperator.getCondition());
+ Type thenType = infer(ternaryOperator.getThenBranch());
+ Type elseType = infer(ternaryOperator.getElseBranch());
+ if (thenType.equals(elseType)) {
+ return thenType;
+ }
+ return Type.UNKNOWN;
+ }
+
+ @Override
+ public Type evaluate(RuntimeCall runtimeCall) {
+ inferAll(runtimeCall.getArguments());
+ return Type.UNKNOWN;
+ }
+
+ @Override
+ public Type evaluate(MapLiteral mapLiteral) {
+ inferAll(mapLiteral.getMap().values());
+ return Type.MAP;
+ }
+
+ @Override
+ public Type evaluate(ArrayLiteral arrayLiteral) {
+ inferAll(arrayLiteral.getItems());
+ return Type.UNKNOWN;
+ }
+
+ @Override
+ public Type evaluate(NullLiteral nullLiteral) {
+ return Type.UNKNOWN;
+ }
+
+ private void inferAll(Iterable<ExpressionNode> nodes) {
+ for (ExpressionNode node : nodes) {
+ infer(node);
+ }
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInfo.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInfo.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/TypeInfo.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.Map;
+
+import org.apache.sling.scripting.sightly.compiled.operator.TypedNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiled.operator.TypedNode;
+
+/**
+ * Provide type information for expressions
+ */
+public class TypeInfo {
+
+ private final Map<ExpressionNode, Type> typeMap;
+
+ public TypeInfo(Map<ExpressionNode, Type> typeMap) {
+ this.typeMap = typeMap;
+ }
+
+ public Type typeOf(ExpressionNode node) {
+ Type type = typeMap.get(node);
+ if (type == null) {
+ return Type.UNKNOWN;
+ }
+ return type;
+ }
+
+ public TypedNode getTyped(ExpressionNode expressionNode) {
+ return new TypedNode(expressionNode, typeOf(expressionNode));
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/UnitBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/UnitBuilder.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/UnitBuilder.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/UnitBuilder.java Fri Nov 14 14:04:56 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.compiled;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Builder for compiled sources
+ */
+public class UnitBuilder {
+
+ private final JavaSource source = new JavaSource();
+ private final Set<String> parameters;
+ private final Map<String, UnitBuilder> subTemplates = new HashMap<String, UnitBuilder>();
+
+ public UnitBuilder() {
+ this(Collections.<String>emptySet());
+ }
+
+ public UnitBuilder(Set<String> parameters) {
+ this.parameters = parameters;
+ }
+
+ public UnitBuilder newSubBuilder(String name, Set<String> parameters) {
+ UnitBuilder unitBuilder = new UnitBuilder(parameters);
+ subTemplates.put(name, unitBuilder);
+ return unitBuilder;
+ }
+
+ public JavaSource getSource() {
+ return source;
+ }
+
+ public Set<String> getParameters() {
+ return parameters;
+ }
+
+ public CompilationOutput build() {
+ Map<String, CompilationOutput> map = new HashMap<String, CompilationOutput>();
+ for (Map.Entry<String, UnitBuilder> entry : subTemplates.entrySet()) {
+ map.put(entry.getKey(), entry.getValue().build());
+ }
+ return new CompilationOutput(source.toString(), map);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableAnalyzer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableAnalyzer.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableAnalyzer.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableAnalyzer.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * 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.compiled;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.sling.scripting.sightly.compiler.util.VariableTracker;
+import org.apache.sling.scripting.sightly.compiler.util.VariableTracker;
+
+/**
+ * Data structure used in the analysis of variables
+ * during the compilation process
+ */
+class VariableAnalyzer {
+
+ private static final HashSet<String> javaKeywords = new HashSet<String>();
+ private final VariableTracker<VariableDescriptor> tracker = new VariableTracker<VariableDescriptor>();
+ private final List<VariableDescriptor> variables = new ArrayList<VariableDescriptor>();
+ private final HashMap<String, VariableDescriptor> dynamicVariables = new HashMap<String, VariableDescriptor>();
+ private final HashMap<String, VariableDescriptor> staticVariables = new HashMap<String, VariableDescriptor>();
+ private static final String DYNAMIC_PREFIX = "_dynamic_";
+ private static final String GLOBAL_PREFIX = "_global_";
+
+ /**
+ * Mark the declaration of a variable in the Java code
+ * @param originalName - the original name of the variable
+ * @return - a variable descriptor uniquely assigned to this variable
+ */
+ public VariableDescriptor declareVariable(String originalName, Type type) {
+ originalName = originalName.toLowerCase();
+ String assignedName = findSafeName(originalName);
+ VariableDescriptor descriptor = new VariableDescriptor(originalName, assignedName, type, VariableScope.SCOPED);
+ tracker.pushVariable(originalName, descriptor);
+ variables.add(descriptor);
+ return descriptor;
+ }
+
+ /**
+ * Declare a global variable. Redundant declarations are ignored
+ * @param originalName - the original name of the variable
+ * @return a variable descriptor
+ */
+ public VariableDescriptor declareGlobal(String originalName) {
+ originalName = originalName.toLowerCase();
+ VariableDescriptor descriptor = staticVariables.get(originalName);
+ if (descriptor == null) {
+ String assignedName = findGlobalName(originalName);
+ descriptor = new VariableDescriptor(originalName, assignedName, Type.UNKNOWN, VariableScope.GLOBAL);
+ variables.add(descriptor);
+ staticVariables.put(originalName, descriptor);
+ }
+ return descriptor;
+ }
+
+ /**
+ * Mark this variable as a template
+ * @param originalName - the original name of the variable
+ * @return a variable descriptor
+ */
+ public VariableDescriptor declareTemplate(String originalName) {
+ originalName = originalName.toLowerCase();
+ VariableDescriptor descriptor = dynamicDescriptor(originalName);
+ descriptor.markAsTemplate();
+ return descriptor;
+ }
+
+ /**
+ * Mark the end of a variable scope
+ */
+ public VariableDescriptor endVariable() {
+ VariableDescriptor descriptor = tracker.peek().getValue();
+ tracker.popVariable();
+ return descriptor;
+ }
+
+ /**
+ * Get a the descriptor for the given variable
+ * @param name the original lowerName of the variable
+ * @return the variable descriptor. If the variable is not in scope,
+ * then a dynamic variable descriptor is provided
+ */
+ public VariableDescriptor descriptor(String name) {
+ String lowerName = name.toLowerCase();
+ VariableDescriptor descriptor = tracker.get(lowerName);
+ if (descriptor == null) {
+ descriptor = staticVariables.get(lowerName);
+ }
+ if (descriptor == null) {
+ descriptor = dynamicDescriptor(lowerName);
+ }
+ return descriptor;
+ }
+
+ /**
+ * Get the collection of all the variables encountered so far
+ * @return an unmodifiable list of all the variables tracked by this analyzer
+ */
+ public Collection<VariableDescriptor> allVariables() {
+ return Collections.unmodifiableList(variables);
+ }
+
+ /**
+ * Shortcut method that returns the assigned name for the given
+ * variable
+ * @param original the original variable name
+ * @return the assigned name for this compilation process
+ */
+ public String assignedName(String original) {
+ return descriptor(original).getAssignedName();
+ }
+
+ private VariableDescriptor dynamicDescriptor(String original) {
+ VariableDescriptor descriptor = dynamicVariables.get(original);
+ if (descriptor == null) {
+ String dynamicName = findDynamicName(original);
+ descriptor = new VariableDescriptor(original, dynamicName, Type.UNKNOWN, VariableScope.DYNAMIC);
+ dynamicVariables.put(original, descriptor);
+ variables.add(descriptor);
+ }
+ return descriptor;
+ }
+
+ private String findDynamicName(String original) {
+ return DYNAMIC_PREFIX + original;
+ }
+
+ private String findGlobalName(String original) {
+ return GLOBAL_PREFIX + syntaxSafeName(original);
+ }
+
+ private String findSafeName(String original) {
+ int occurrenceCount = tracker.getOccurrenceCount(original);
+ String syntaxSafe = syntaxSafeName(original);
+ if (occurrenceCount == 0) {
+ return syntaxSafe; //no other declarations in scope. Use this very name
+ } else {
+ return original + "_" + occurrenceCount;
+ }
+ }
+
+ private String syntaxSafeName(String original) {
+ if (javaKeywords.contains(original)) {
+ return "_" + original;
+ }
+ return original.replaceAll("-", "_");
+ }
+
+ static {
+ javaKeywords.add("abstract");
+ javaKeywords.add("continue");
+ javaKeywords.add("for");
+ javaKeywords.add("new");
+ javaKeywords.add("switch");
+ javaKeywords.add("assert");
+ javaKeywords.add("default");
+ javaKeywords.add("goto");
+ javaKeywords.add("package");
+ javaKeywords.add("synchronized");
+ javaKeywords.add("boolean");
+ javaKeywords.add("do");
+ javaKeywords.add("if");
+ javaKeywords.add("private");
+ javaKeywords.add("this");
+ javaKeywords.add("break");
+ javaKeywords.add("double");
+ javaKeywords.add("implements");
+ javaKeywords.add("protected");
+ javaKeywords.add("throw");
+ javaKeywords.add("byte");
+ javaKeywords.add("else");
+ javaKeywords.add("import");
+ javaKeywords.add("public");
+ javaKeywords.add("throws");
+ javaKeywords.add("case");
+ javaKeywords.add("enum");
+ javaKeywords.add("instanceof");
+ javaKeywords.add("return");
+ javaKeywords.add("transient");
+ javaKeywords.add("catch");
+ javaKeywords.add("extends");
+ javaKeywords.add("int");
+ javaKeywords.add("short");
+ javaKeywords.add("try");
+ javaKeywords.add("char");
+ javaKeywords.add("final");
+ javaKeywords.add("interface");
+ javaKeywords.add("static");
+ javaKeywords.add("void");
+ javaKeywords.add("class");
+ javaKeywords.add("finally");
+ javaKeywords.add("long");
+ javaKeywords.add("strictfp");
+ javaKeywords.add("volatile");
+ javaKeywords.add("const");
+ javaKeywords.add("float");
+ javaKeywords.add("native");
+ javaKeywords.add("super");
+ javaKeywords.add("while");
+ }
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableDescriptor.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableDescriptor.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableDescriptor.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableDescriptor.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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.compiled;
+
+/**
+ * Information about a variable during the compilation process
+ */
+public class VariableDescriptor {
+
+ private final String originalName;
+ private final String assignedName;
+ private VariableScope scope;
+ private String listCoercion;
+ private final Type type;
+ private boolean templateVariable;
+
+ public VariableDescriptor(String originalName, String assignedName, Type type, VariableScope scope) {
+ this.originalName = originalName;
+ this.assignedName = assignedName;
+ this.scope = scope;
+ this.type = type;
+ }
+
+ /**
+ * The name of the list coercion variable
+ * @return - the variable that will hold the list coercion
+ */
+ public String requireListCoercion() {
+ if (listCoercion == null) {
+ listCoercion = assignedName + "_list_coerced$";
+ }
+ return listCoercion;
+ }
+
+ public String getListCoercion() {
+ return listCoercion;
+ }
+
+ /**
+ * Get the original name of the variable, as it was provided
+ * by the command that introduced the variable
+ * @return - the original variable name
+ */
+ public String getOriginalName() {
+ return originalName;
+ }
+
+ /**
+ * Get the assigned name for the variable - the name that will
+ * actually be used during compilation
+ * @return - the assigned variable name
+ */
+ public String getAssignedName() {
+ return assignedName;
+ }
+
+ /**
+ * Get the scope of this variable
+ * @return the variable scope
+ */
+ public VariableScope getScope() {
+ return scope;
+ }
+
+ /**
+ * Get the inferred type fot this variable
+ * @return - the class of the variable
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * Check whether this is a template variable
+ * @return true if it is a template variable
+ */
+ public boolean isTemplateVariable() {
+ return templateVariable;
+ }
+
+ /**
+ * Signal that this variable stands for a template
+ */
+ public void markAsTemplate() {
+ if (scope != VariableScope.DYNAMIC) {
+ throw new UnsupportedOperationException("Only dynamic variables can be marked as templates");
+ }
+ templateVariable = true;
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableScope.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableScope.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableScope.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/VariableScope.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.compiled;
+
+/**
+ * The scope of a variable in a Sightly script
+ */
+public enum VariableScope {
+ DYNAMIC, SCOPED, GLOBAL
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/BinaryOpGen.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/BinaryOpGen.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/BinaryOpGen.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/BinaryOpGen.java Fri Nov 14 14:04:56 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.compiled.operator;
+
+import org.apache.sling.scripting.sightly.compiled.ExpressionTranslator;
+import org.apache.sling.scripting.sightly.compiled.JavaSource;
+import org.apache.sling.scripting.sightly.compiled.Type;
+import org.apache.sling.scripting.sightly.compiled.Type;
+
+/**
+ * Generator for a binary operator
+ */
+public interface BinaryOpGen {
+
+ Type returnType(Type leftType, Type rightType);
+
+ void generate(JavaSource source, ExpressionTranslator visitor, TypedNode left, TypedNode right);
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ComparisonOpGen.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ComparisonOpGen.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ComparisonOpGen.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ComparisonOpGen.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.compiled.operator;
+
+import org.apache.sling.scripting.sightly.api.ObjectModel;
+import org.apache.sling.scripting.sightly.compiled.ExpressionTranslator;
+import org.apache.sling.scripting.sightly.compiled.JavaSource;
+import org.apache.sling.scripting.sightly.compiled.SourceGenConstants;
+import org.apache.sling.scripting.sightly.compiled.Type;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.api.expression.node.BinaryOperator;
+import org.apache.sling.scripting.sightly.compiler.util.expression.SideEffectVisitor;
+import org.apache.sling.scripting.sightly.compiled.SourceGenConstants;
+
+/**
+ * Generator for logical operators
+ */
+public class ComparisonOpGen implements BinaryOpGen {
+
+ private final String javaOperator;
+ private final boolean inverted;
+ private final String runtimeMethod;
+
+ public ComparisonOpGen(BinaryOperator operator) {
+ switch (operator) {
+ case LT: runtimeMethod = ObjectModel.LT; inverted = false; javaOperator = "<"; break;
+ case GT: runtimeMethod = ObjectModel.LEQ; inverted = true; javaOperator = ">"; break;
+ case LEQ: runtimeMethod = ObjectModel.LEQ; inverted = false; javaOperator = "<="; break;
+ case GEQ: runtimeMethod = ObjectModel.LT; inverted = true; javaOperator = ">="; break;
+ default: throw new IllegalArgumentException("Operator is not a comparison operator: " + operator);
+ }
+ }
+
+ @Override
+ public Type returnType(Type left, Type right) {
+ return Type.BOOLEAN;
+ }
+
+ @Override
+ public void generate(JavaSource source, ExpressionTranslator visitor, TypedNode left, TypedNode right) {
+ Type type = OpHelper.sameType(left, right);
+ if (OpHelper.isNumericType(type)) {
+ generateWithOperator(source, visitor, left.getNode(), right.getNode());
+ } else {
+ generateGeneric(source, visitor, left.getNode(), right.getNode());
+ }
+ }
+
+ private void generateGeneric(JavaSource source, SideEffectVisitor visitor, ExpressionNode leftNode, ExpressionNode rightNode) {
+ if (inverted) {
+ source.negation().startExpression();
+ }
+ source.startMethodCall(SourceGenConstants.OBJ_MODEL_INSTANCE, runtimeMethod);
+ leftNode.accept(visitor);
+ source.separateArgument();
+ rightNode.accept(visitor);
+ source.endCall();
+ if (inverted) {
+ source.endExpression();
+ }
+ }
+
+ private void generateWithOperator(JavaSource source, SideEffectVisitor visitor,
+ ExpressionNode leftNode, ExpressionNode rightNode) {
+ leftNode.accept(visitor);
+ source.append(javaOperator);
+ rightNode.accept(visitor);
+ }
+
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ConcatenateOpGen.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ConcatenateOpGen.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ConcatenateOpGen.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/ConcatenateOpGen.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.compiled.operator;
+
+import org.apache.sling.scripting.sightly.compiled.ExpressionTranslator;
+import org.apache.sling.scripting.sightly.compiled.GenHelper;
+import org.apache.sling.scripting.sightly.compiled.JavaSource;
+import org.apache.sling.scripting.sightly.compiled.Type;
+
+/**
+ * Concatenation operator generation
+ */
+public final class ConcatenateOpGen implements BinaryOpGen {
+
+ public static final ConcatenateOpGen INSTANCE = new ConcatenateOpGen();
+
+ private ConcatenateOpGen() {
+ }
+
+ @Override
+ public Type returnType(Type leftType, Type rightType) {
+ return Type.STRING;
+ }
+
+ @Override
+ public void generate(JavaSource source, ExpressionTranslator visitor, TypedNode left, TypedNode right) {
+ GenHelper.typeCoercion(source, visitor, left, Type.STRING);
+ source.append("+");
+ GenHelper.typeCoercion(source, visitor, right, Type.STRING);
+ }
+}
Added: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/EquivalenceOpGen.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/EquivalenceOpGen.java?rev=1639641&view=auto
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/EquivalenceOpGen.java (added)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/compiled/operator/EquivalenceOpGen.java Fri Nov 14 14:04:56 2014
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * 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.compiled.operator;
+
+import org.apache.sling.scripting.sightly.compiled.ExpressionTranslator;
+import org.apache.sling.scripting.sightly.compiled.JavaSource;
+import org.apache.sling.scripting.sightly.compiled.Type;
+import org.apache.sling.scripting.sightly.compiler.api.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.util.expression.SideEffectVisitor;
+
+/**
+ * Generator for logical operators
+ */
+public class EquivalenceOpGen implements BinaryOpGen {
+
+ private final boolean negated;
+
+ public EquivalenceOpGen(boolean negated) {
+ this.negated = negated;
+ }
+
+ @Override
+ public Type returnType(Type left, Type right) {
+ return Type.BOOLEAN;
+ }
+
+ @Override
+ public void generate(JavaSource source, ExpressionTranslator visitor, TypedNode left, TypedNode right) {
+ Type type = OpHelper.sameType(left, right);
+ if (type != null && OpHelper.isNumericType(type) || type == Type.BOOLEAN) {
+ generateEqualsOperator(source, visitor, left.getNode(), right.getNode());
+ } else if (type != Type.UNKNOWN) {
+ generateEqualsMethod(source, visitor, left, right);
+ } else {
+ generateCheckedEquals(source, visitor, left, right);
+ }
+ }
+
+ private void generateCheckedEquals(JavaSource source, SideEffectVisitor visitor, TypedNode leftNode, TypedNode rightNode) {
+ source.startExpression();
+ leftNode.getNode().accept(visitor);
+ source.equality().nullLiteral().conditional();
+ rightNode.getNode().accept(visitor);
+ source.equality().nullLiteral();
+ source.conditionalBranchSep();
+ generateEqualsMethod(source, visitor, leftNode, rightNode);
+ }
+
+ private void generateEqualsMethod(JavaSource source, SideEffectVisitor visitor, TypedNode leftNode, TypedNode rightNode) {
+ boolean performCast = leftNode.getType().isPrimitive();
+ if (performCast) {
+ source.startExpression();
+ source.cast(Type.UNKNOWN.getNativeClass());
+ }
+ leftNode.getNode().accept(visitor);
+ if (performCast) {
+ source.endExpression();
+ }
+ source.startCall("equals", true);
+ rightNode.getNode().accept(visitor);
+ source.endCall();
+ }
+
+ private void generateEqualsOperator(JavaSource source, SideEffectVisitor visitor, ExpressionNode leftNode, ExpressionNode rightNode) {
+ leftNode.accept(visitor);
+ source.append(operator());
+ rightNode.accept(visitor);
+ }
+
+ private String operator() {
+ return (negated) ? "!=" : "==";
+ }
+
+}