@Override public SoyData compute(List<SoyData> args) { SoyData arg0 = args.get(0); SoyData arg1 = args.get(1); if (arg0 instanceof IntegerData && arg1 instanceof IntegerData) { return toSoyData(Math.max(arg0.integerValue(), arg1.integerValue())); } else { return toSoyData(Math.max(arg0.numberValue(), arg1.numberValue())); } }
@Override public SoyData compute(List<SoyData> args) { SoyData arg0 = args.get(0); SoyData arg1 = args.get(1); if (arg0 instanceof IntegerData && arg1 instanceof IntegerData) { return toSoyData(Math.min(arg0.integerValue(), arg1.integerValue())); } else { return toSoyData(Math.min(arg0.numberValue(), arg1.numberValue())); } }
@Override public SoyData compute(List<SoyData> args) { SoyData value = args.get(0); int numDigitsAfterPt = (args.size() == 2) ? args.get(1).integerValue() : 0 /* default */; if (numDigitsAfterPt == 0) { if (value instanceof IntegerData) { return toSoyData(value.integerValue()); } else { return toSoyData((int) Math.round(value.numberValue())); } } else if (numDigitsAfterPt > 0) { double valueDouble = value.numberValue(); double shift = Math.pow(10, numDigitsAfterPt); return toSoyData(Math.round(valueDouble * shift) / shift); } else { double valueDouble = value.numberValue(); double shift = Math.pow(10, -numDigitsAfterPt); return toSoyData((int) (Math.round(valueDouble / shift) * shift)); } }
@Override protected SoyData visitDivideByOpNode(DivideByOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); // Note: Soy always performs floating-point division, even on two integers (like JavaScript). return convertResult(operand0.numberValue() / operand1.numberValue()); }
public static SoyData $$plus(SoyData operand0, SoyData operand1) { if (operand0 instanceof NumberData && operand1 instanceof NumberData) { if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return IntegerData.forValue(operand0.integerValue() + operand1.integerValue()); } else { return FloatData.forValue(operand0.numberValue() + operand1.numberValue()); } } else { // String concatenation. Note we're calling toString() instead of stringValue() in case one // of the operands needs to be coerced to a string. return StringData.forValue(operand0.toString() + operand1.toString()); } }
@Override protected SoyData visitLessThanOrEqualOpNode(LessThanOrEqualOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() <= operand1.integerValue()); } else { return convertResult(operand0.numberValue() <= operand1.numberValue()); } }
@Override protected SoyData visitMinusOpNode(MinusOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() - operand1.integerValue()); } else { return convertResult(operand0.numberValue() - operand1.numberValue()); } }
@Override protected SoyData visitGreaterThanOpNode(GreaterThanOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() > operand1.integerValue()); } else { return convertResult(operand0.numberValue() > operand1.numberValue()); } }
@Override protected SoyData visitGreaterThanOrEqualOpNode(GreaterThanOrEqualOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() >= operand1.integerValue()); } else { return convertResult(operand0.numberValue() >= operand1.numberValue()); } }
@Override protected SoyData visitTimesOpNode(TimesOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() * operand1.integerValue()); } else { return convertResult(operand0.numberValue() * operand1.numberValue()); } }
@Override protected SoyData visitLessThanOpNode(LessThanOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() < operand1.integerValue()); } else { return convertResult(operand0.numberValue() < operand1.numberValue()); } }
@Override protected SoyData visitPlusOpNode(PlusOpNode node) { SoyData operand0 = visit(node.getChild(0)); SoyData operand1 = visit(node.getChild(1)); if (operand0 instanceof IntegerData && operand1 instanceof IntegerData) { return convertResult(operand0.integerValue() + operand1.integerValue()); } else if (operand0 instanceof StringData || operand1 instanceof StringData) { // String concatenation. Note we're calling toString() instead of stringValue() in case one // of the operands needs to be coerced to a string. return convertResult(operand0.toString() + operand1.toString()); } else { return convertResult(operand0.numberValue() + operand1.numberValue()); } }
/** * Converts the input to a JavaScript expression. The resulting expression can be a boolean, * number, string literal, or {@code null}. */ public static String escapeJsValue(SoyData value) { // We surround values with spaces so that they can't be interpolated into identifiers // by accident. We could use parentheses but those might be interpreted as a function call. if (NullData.INSTANCE == value) { // The JS counterpart of this code in soyutils.js emits " null " for both null and the special // JS value undefined. return " null "; } else if (value instanceof NumberData) { // This will emit references to NaN and Infinity. Client code should not redefine those // to store sensitive data. return " " + value.numberValue() + " "; } else if (value instanceof BooleanData) { return " " + value.booleanValue() + " "; } else if (isSanitizedContentOfKind(value, SanitizedContent.ContentKind.JS)) { return value.toString(); } else { return escapeJsValue(value.toString()); } }