diff --git a/java/src/com/google/template/soy/basicfunctions/BasicFunctionsRuntime.java b/java/src/com/google/template/soy/basicfunctions/BasicFunctionsRuntime.java index 06a648334e..b1d5d285ff 100644 --- a/java/src/com/google/template/soy/basicfunctions/BasicFunctionsRuntime.java +++ b/java/src/com/google/template/soy/basicfunctions/BasicFunctionsRuntime.java @@ -254,7 +254,7 @@ private static void listFlatImpl( public static ImmutableList numberListSort( List list) { return ImmutableList.sortedCopyOf( - comparingDouble((SoyValueProvider arg) -> arg.resolve().numberValue()), list); + comparingDouble((SoyValueProvider arg) -> arg.resolve().floatValue()), list); } @Nonnull @@ -344,7 +344,7 @@ public static NumberData max(SoyValue arg0, SoyValue arg1) { if (arg0 instanceof IntegerData && arg1 instanceof IntegerData) { return IntegerData.forValue(Math.max(arg0.longValue(), arg1.longValue())); } else { - return FloatData.forValue(Math.max(arg0.numberValue(), arg1.numberValue())); + return FloatData.forValue(Math.max(arg0.floatValue(), arg1.floatValue())); } } @@ -353,7 +353,7 @@ public static NumberData min(SoyValue arg0, SoyValue arg1) { if (arg0 instanceof IntegerData && arg1 instanceof IntegerData) { return IntegerData.forValue(Math.min(arg0.longValue(), arg1.longValue())); } else { - return FloatData.forValue(Math.min(arg0.numberValue(), arg1.numberValue())); + return FloatData.forValue(Math.min(arg0.floatValue(), arg1.floatValue())); } } @@ -365,7 +365,7 @@ public static FloatData parseFloat(String str) { @Nullable public static IntegerData parseInt(String str, SoyValue radixVal) { - int radix = SoyValue.isNullish(radixVal) ? 10 : (int) radixVal.numberValue(); + int radix = SoyValue.isNullish(radixVal) ? 10 : (int) radixVal.floatValue(); if (radix < 2 || radix > 36) { return null; } @@ -389,11 +389,11 @@ public static NumberData round(SoyValue value, int numDigitsAfterPoint) { if (numDigitsAfterPoint == 0) { return IntegerData.forValue(round(value)); } else if (numDigitsAfterPoint > 0) { - double valueDouble = value.numberValue(); + double valueDouble = value.floatValue(); double shift = Math.pow(10, numDigitsAfterPoint); return FloatData.forValue(Math.round(valueDouble * shift) / shift); } else { - double valueDouble = value.numberValue(); + double valueDouble = value.floatValue(); double shift = Math.pow(10, -numDigitsAfterPoint); return IntegerData.forValue((int) (Math.round(valueDouble / shift) * shift)); } @@ -404,7 +404,7 @@ public static long round(SoyValue value) { if (value instanceof IntegerData) { return value.longValue(); } else { - return Math.round(value.numberValue()); + return Math.round(value.floatValue()); } } @@ -465,7 +465,7 @@ public static String strSub(SoyValue str, NumberData start) { public static String strSub(SoyValue str, NumberData start, NumberData end) { // TODO(b/74259210) -- Change the first param to String & avoid using stringValue(). - if (start.numberValue() > end.numberValue()) { + if (start.floatValue() > end.floatValue()) { return strSub(str, end, start); } String string = str.stringValue(); @@ -496,7 +496,7 @@ public static ImmutableList strSplit(String str, String sep, NumberD ImmutableList.Builder builder = ImmutableList.builder(); int truncLimit = -1; if (limit != null) { - truncLimit = (int) limit.numberValue(); + truncLimit = (int) limit.floatValue(); } if (truncLimit == 0) { return builder.build(); @@ -541,7 +541,7 @@ public static boolean protoEquals(Message proto1, Message proto2) { } private static int clampListIndex(List list, NumberData index) { - int truncIndex = (int) index.numberValue(); + int truncIndex = (int) index.floatValue(); int size = list.size(); int clampLowerBound = Math.max(0, truncIndex >= 0 ? truncIndex : size + truncIndex); // Clamp upper bound @@ -549,14 +549,14 @@ private static int clampListIndex(List list, NumberData index) { } private static int clampStrIndex(String str, NumberData position) { - int clampLowerBound = Math.max(0, (int) position.numberValue()); + int clampLowerBound = Math.max(0, (int) position.floatValue()); // Clamp upper bound return Math.min(str.length(), clampLowerBound); } /** Returns whether the argument is a finite value (not NaN or Infinity). */ public static boolean isFinite(SoyValue arg) { - return arg instanceof NumberData && Double.isFinite(arg.numberValue()); + return arg instanceof NumberData && Double.isFinite(arg.floatValue()); } private static String joinHelper(List values, String delimiter) { diff --git a/java/src/com/google/template/soy/data/ProtoFieldInterpreter.java b/java/src/com/google/template/soy/data/ProtoFieldInterpreter.java index cec9a160ea..f6f90357a0 100644 --- a/java/src/com/google/template/soy/data/ProtoFieldInterpreter.java +++ b/java/src/com/google/template/soy/data/ProtoFieldInterpreter.java @@ -322,7 +322,7 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { - return Ints.saturatedCast(field.coerceToLong()); + return Ints.saturatedCast(field.longValue()); } }; @@ -336,7 +336,7 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { - return UnsignedInts.saturatedCast(field.coerceToLong()); + return UnsignedInts.saturatedCast(field.longValue()); } }; @@ -351,9 +351,9 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { if (field instanceof GbigintData) { - return ((GbigintData) field).longValue(); + return field.longValue(); } - return field.coerceToLong(); + return field.longValue(); } }; @@ -368,7 +368,7 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { if (field instanceof GbigintData) { - return ((GbigintData) field).longValue(); + return field.longValue(); } return Long.parseLong(field.stringValue()); } @@ -446,7 +446,7 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { - return (float) field.numberValue(); + return (float) field.floatValue(); } }; @@ -460,7 +460,7 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { - return field.numberValue(); + return field.floatValue(); } }; @@ -612,7 +612,7 @@ public SoyValue soyFromProto(Object field) { @Override public Object protoFromSoy(SoyValue field) { - return ((SoyProtoValue) field).getProto(); + return field.getProto(); } }; diff --git a/java/src/com/google/template/soy/data/SoyValue.java b/java/src/com/google/template/soy/data/SoyValue.java index e195aafa4b..c74cc55767 100644 --- a/java/src/com/google/template/soy/data/SoyValue.java +++ b/java/src/com/google/template/soy/data/SoyValue.java @@ -89,12 +89,14 @@ public SoyValueProvider coerceToBooleanProvider() { * #longValue()} this method is expected to succeed for any {@link * com.google.template.soy.data.restricted.NumberData}. */ - public long coerceToLong() { - throw new SoyDataException("'" + this + "' cannot be coerced to long"); + @Deprecated + public final long coerceToLong() { + return longValue(); } - public int coerceToInt() { - throw new SoyDataException("'" + this + "' cannot be coerced to int"); + @Deprecated + public final int coerceToInt() { + return integerValue(); } /** diff --git a/java/src/com/google/template/soy/data/restricted/FloatData.java b/java/src/com/google/template/soy/data/restricted/FloatData.java index b637b586e7..3ee54bdbe0 100644 --- a/java/src/com/google/template/soy/data/restricted/FloatData.java +++ b/java/src/com/google/template/soy/data/restricted/FloatData.java @@ -18,7 +18,7 @@ import com.google.errorprone.annotations.Immutable; import com.google.template.soy.base.internal.BaseUtils; -import com.google.template.soy.data.SoyValue; +import com.google.template.soy.base.internal.NumericCoercions; import javax.annotation.Nonnull; /** Float data. */ @@ -48,11 +48,6 @@ public double getValue() { return value; } - @Override - public double floatValue() { - return value; - } - @Override @Nonnull public String toString() { @@ -75,18 +70,23 @@ public String coerceToString() { } @Override - public double toFloat() { + public double floatValue() { return value; } @Override - public Number javaNumberValue() { - return value; + public boolean isSafeJsInteger() { + return value % 1 == 0 && NumericCoercions.isInRange((long) value); + } + + @Override + public long longValue() { + return NumericCoercions.safeLong(value); } @Override - public SoyValue checkNullishFloat() { - return this; + public int integerValue() { + return NumericCoercions.safeInt(value); } @Override diff --git a/java/src/com/google/template/soy/data/restricted/IntegerData.java b/java/src/com/google/template/soy/data/restricted/IntegerData.java index 2de75624ae..170ee7d004 100644 --- a/java/src/com/google/template/soy/data/restricted/IntegerData.java +++ b/java/src/com/google/template/soy/data/restricted/IntegerData.java @@ -18,7 +18,6 @@ import com.google.errorprone.annotations.Immutable; import com.google.template.soy.base.internal.NumericCoercions; -import com.google.template.soy.data.SoyValue; import javax.annotation.Nonnull; /** Integer data. */ @@ -116,6 +115,10 @@ public long getValue() { return value; } + public boolean isSafeJsInteger() { + return NumericCoercions.isInRange(value); + } + @Override public int integerValue() { return NumericCoercions.safeInt(value); @@ -148,12 +151,7 @@ public String coerceToString() { } @Override - public double toFloat() { - return value; - } - - @Override - public Number javaNumberValue() { + public double floatValue() { return value; } @@ -169,11 +167,6 @@ public boolean equals(Object other) { } } - @Override - public SoyValue checkNullishInt() { - return this; - } - @Override public long coerceToIndex() { return value; diff --git a/java/src/com/google/template/soy/data/restricted/NumberData.java b/java/src/com/google/template/soy/data/restricted/NumberData.java index d2423c995a..dbdf594b43 100644 --- a/java/src/com/google/template/soy/data/restricted/NumberData.java +++ b/java/src/com/google/template/soy/data/restricted/NumberData.java @@ -17,60 +17,41 @@ package com.google.template.soy.data.restricted; import com.google.common.primitives.Longs; -import com.google.template.soy.base.internal.NumericCoercions; import com.google.template.soy.data.SoyValue; -import javax.annotation.Nonnull; /** Abstract superclass for number data (integers and floats). */ public abstract class NumberData extends PrimitiveData { - /** - * Gets the float value of this number data object. If this object is actually an integer, its - * value will be converted to a float before being returned. - * - * @return The float value of this number data object. - */ - public abstract double toFloat(); - - /** - * Returns true if this value is a whole integer in the range representable in JavaScript without - * a loss of precision. - */ - public boolean isSafeJsInteger() { - double val = numberValue(); - return val % 1 == 0 && NumericCoercions.isInRange((long) val); - } - @Override - public long coerceToLong() { - return javaNumberValue().longValue(); + public final SoyValue checkNullishInt() { + return this; } @Override - public int coerceToInt() { - long l = coerceToLong(); - if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) { - throw new IllegalArgumentException(); - } - return (int) l; + public final SoyValue checkNullishFloat() { + return this; } + /** + * Returns true if this value is a whole integer in the range representable in JavaScript without + * a loss of precision. + */ + public abstract boolean isSafeJsInteger(); + @Override - public double numberValue() { - return toFloat(); + @Deprecated + public final double numberValue() { + return floatValue(); } - @Nonnull - public abstract Number javaNumberValue(); - @Override public boolean equals(Object other) { - return other instanceof NumberData && ((NumberData) other).toFloat() == this.toFloat(); + return other instanceof NumberData && ((NumberData) other).floatValue() == this.floatValue(); } @Override public int hashCode() { - return Longs.hashCode(Double.doubleToLongBits(toFloat())); + return Longs.hashCode(Double.doubleToLongBits(floatValue())); } @Override diff --git a/java/src/com/google/template/soy/i18ndirectives/I18NDirectivesRuntime.java b/java/src/com/google/template/soy/i18ndirectives/I18NDirectivesRuntime.java index 1fe0548507..cfdfcf5a88 100644 --- a/java/src/com/google/template/soy/i18ndirectives/I18NDirectivesRuntime.java +++ b/java/src/com/google/template/soy/i18ndirectives/I18NDirectivesRuntime.java @@ -52,11 +52,11 @@ public static String formatNum( } else if (number instanceof NumberData) { return formatInternal( uLocale, - ((NumberData) number).toFloat(), + ((NumberData) number).floatValue(), formatType, numbersKeyword, - minFractionDigits != null ? (int) minFractionDigits.numberValue() : null, - maxFractionDigits != null ? (int) maxFractionDigits.numberValue() : null); + minFractionDigits != null ? (int) minFractionDigits.floatValue() : null, + maxFractionDigits != null ? (int) maxFractionDigits.floatValue() : null); } else { return "NaN"; } diff --git a/java/src/com/google/template/soy/jbcsrc/ProtoUtils.java b/java/src/com/google/template/soy/jbcsrc/ProtoUtils.java index efb43cf315..5cf56287f3 100644 --- a/java/src/com/google/template/soy/jbcsrc/ProtoUtils.java +++ b/java/src/com/google/template/soy/jbcsrc/ProtoUtils.java @@ -1896,7 +1896,7 @@ private static Type unboxUnchecked( } if (asType.equals(double.class)) { - MethodRefs.SOY_VALUE_NUMBER_VALUE.invokeUnchecked(cb); + MethodRefs.SOY_VALUE_FLOAT_VALUE.invokeUnchecked(cb); return Type.DOUBLE_TYPE; } diff --git a/java/src/com/google/template/soy/jbcsrc/restricted/MethodRefs.java b/java/src/com/google/template/soy/jbcsrc/restricted/MethodRefs.java index 78874a25da..d9e5490675 100644 --- a/java/src/com/google/template/soy/jbcsrc/restricted/MethodRefs.java +++ b/java/src/com/google/template/soy/jbcsrc/restricted/MethodRefs.java @@ -61,7 +61,6 @@ import com.google.template.soy.data.restricted.FloatData; import com.google.template.soy.data.restricted.GbigintData; import com.google.template.soy.data.restricted.IntegerData; -import com.google.template.soy.data.restricted.NumberData; import com.google.template.soy.data.restricted.StringData; import com.google.template.soy.jbcsrc.api.RenderResult; import com.google.template.soy.jbcsrc.restricted.MethodRef.MethodPureness; @@ -517,10 +516,6 @@ public final class MethodRefs { public static final MethodRef SOY_VALUE_INTEGER_VALUE = createPure(SoyValue.class, "integerValue").asCheap(); - public static final MethodRef SOY_VALUE_NUMBER_VALUE = createPure(SoyValue.class, "numberValue"); - public static final MethodRef SOY_VALUE_COERCE_TO_LONG = - createPure(SoyValue.class, "coerceToLong"); - public static final MethodRef SOY_VALUE_COERCE_TO_INT = createPure(SoyValue.class, "coerceToInt"); public static final MethodRef INT_TO_NUMBER = createPure(JbcSrcRuntime.class, "intToNumber", SoyValue.class); public static final MethodRef NUMBER_TO_INT = @@ -542,7 +537,7 @@ public final class MethodRefs { createPure(SoyValue.class, "nullishToUndefined").asCheap().asNonJavaNullable(); public static final MethodRef SOY_VALUE_JAVA_NUMBER_VALUE = - createPure(NumberData.class, "javaNumberValue"); + createPure(JbcSrcRuntime.class, "javaNumberValue", SoyValue.class); public static final MethodRef SOY_VALUE_STRING_VALUE = createPure(SoyValue.class, "stringValue").asCheap(); diff --git a/java/src/com/google/template/soy/jbcsrc/restricted/SoyExpression.java b/java/src/com/google/template/soy/jbcsrc/restricted/SoyExpression.java index 769f122907..4dcaa50023 100644 --- a/java/src/com/google/template/soy/jbcsrc/restricted/SoyExpression.java +++ b/java/src/com/google/template/soy/jbcsrc/restricted/SoyExpression.java @@ -600,10 +600,7 @@ public SoyExpression coerceToDouble() { } throw new UnsupportedOperationException("Can't convert " + resultType() + " to a double"); } - if (soyRuntimeType.isKnownFloat()) { - return forFloat(delegate.invoke(MethodRefs.SOY_VALUE_FLOAT_VALUE).toMaybeConstant()); - } - return forFloat(delegate.invoke(MethodRefs.SOY_VALUE_NUMBER_VALUE).toMaybeConstant()); + return forFloat(delegate.invoke(MethodRefs.SOY_VALUE_FLOAT_VALUE).toMaybeConstant()); } /** @@ -622,8 +619,7 @@ public Expression unboxAsNumberOrJavaNull() { throw new UnsupportedOperationException("Can't convert " + resultType() + " to a Number"); } if (isNonSoyNullish()) { - return MethodRefs.SOY_VALUE_JAVA_NUMBER_VALUE.invoke( - this.checkedCast(BytecodeUtils.NUMBER_DATA_TYPE)); + return MethodRefs.SOY_VALUE_JAVA_NUMBER_VALUE.invoke(this); } return new Expression(BytecodeUtils.NUMBER_TYPE, featuresAfterUnboxing()) { @Override @@ -631,7 +627,7 @@ protected void doGen(CodeBuilder adapter) { Label end = newLabel(); delegate.gen(adapter); BytecodeUtils.coalesceSoyNullishToJavaNull(adapter, delegate.resultType(), end); - adapter.checkCast(BytecodeUtils.NUMBER_DATA_TYPE); + MethodRefs.SOY_VALUE_JAVA_NUMBER_VALUE.invokeUnchecked(adapter); adapter.mark(end); } @@ -1019,13 +1015,13 @@ public SoyExpression coerceTo(Type runtimeType) { switch (runtimeType.getSort()) { case Type.LONG: if (isBoxed()) { - return forInt(MethodRefs.SOY_VALUE_COERCE_TO_LONG.invoke(delegate)); + return forInt(MethodRefs.SOY_VALUE_LONG_VALUE.invoke(delegate)); } else { return forInt(BytecodeUtils.numericConversion(delegate, Type.LONG_TYPE)); } case Type.INT: if (isBoxed()) { - return forInt(MethodRefs.SOY_VALUE_COERCE_TO_INT.invoke(delegate)); + return forInt(MethodRefs.SOY_VALUE_INTEGER_VALUE.invoke(delegate)); } else { return forInt(BytecodeUtils.numericConversion(delegate, Type.INT_TYPE)); } diff --git a/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcExternRuntime.java b/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcExternRuntime.java index 73e2c60e21..e55ffe80cd 100644 --- a/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcExternRuntime.java +++ b/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcExternRuntime.java @@ -196,7 +196,7 @@ public static ImmutableList listUnboxNumbers(List values) { if (values == null) { return null; } - return values.stream().map(SoyValue::numberValue).collect(toImmutableList()); + return values.stream().map(SoyValue::floatValue).collect(toImmutableList()); } public static final MethodRef LIST_UNBOX_PROTOS = create("listUnboxProtos", List.class); @@ -262,7 +262,7 @@ public static Double toBoxedDouble(SoyValue value) { if (value.isNullish()) { return null; } else if (value instanceof NumberData) { - return value.numberValue(); + return value.floatValue(); } // This is probably an error, in which case this call with throw an appropriate exception. return value.floatValue(); @@ -276,7 +276,7 @@ public static Float toBoxedFloat(SoyValue value) { if (value.isNullish()) { return null; } else if (value instanceof NumberData) { - return (float) value.numberValue(); + return (float) value.floatValue(); } // This is probably an error, in which case this call with throw an appropriate exception. return (float) value.floatValue(); diff --git a/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcRuntime.java b/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcRuntime.java index 941a61a22a..acd9d0514b 100644 --- a/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcRuntime.java +++ b/java/src/com/google/template/soy/jbcsrc/runtime/JbcSrcRuntime.java @@ -482,7 +482,7 @@ public RenderResult renderAndResolve(LoggingAdvisingAppendable out) throws IOExc SoyValueProvider pluralPlaceholder = getPlaceholder(pluralPart.getPluralVarName()); var caseSelectionResult = pluralPlaceholder.status(); if (caseSelectionResult.isDone()) { - double pluralValue = pluralPlaceholder.resolve().numberValue(); + double pluralValue = pluralPlaceholder.resolve().floatValue(); msgParts = pluralPart.lookupCase(pluralValue, locale); } else { return caseSelectionResult; @@ -580,7 +580,7 @@ public static boolean compareUnboxedStringToBoxed(String stringValue, SoyValue o if (other instanceof NumberData) { try { // Parse the string as a number. - return Double.parseDouble(stringValue) == other.numberValue(); + return Double.parseDouble(stringValue) == other.floatValue(); } catch (NumberFormatException nfe) { // Didn't parse as a number. return false; @@ -589,6 +589,16 @@ public static boolean compareUnboxedStringToBoxed(String stringValue, SoyValue o return false; } + @Nonnull + @Keep + public static Number javaNumberValue(SoyValue value) { + if (value instanceof IntegerData) { + return value.longValue(); + } else { + return value.floatValue(); + } + } + @Nonnull @Keep public static LoggingAdvisingAppendable logger() { @@ -1047,7 +1057,7 @@ public static int asSwitchableValue(double value, int unusedKey) { public static int asSwitchableValue(SoyValue value, int unusedKey) { if (value instanceof NumberData) { - return asSwitchableValue(value.numberValue(), unusedKey); + return asSwitchableValue(value.floatValue(), unusedKey); } return unusedKey; } @@ -1099,10 +1109,10 @@ private EveryDetachStateForTesting() {} public static long convertSoyValueToProtoLong(SoyValue value) { if (value instanceof GbigintData) { - return ((GbigintData) value).longValue(); + return value.longValue(); } if (value instanceof NumberData) { - return ((NumberData) value).coerceToLong(); + return value.longValue(); } return Long.parseLong(value.stringValue()); @@ -1113,7 +1123,7 @@ public static long convertSoyValueToProtoUnsignedLong(SoyValue value) { return ((GbigintData) value).unsignedLongValue(); } if (value instanceof NumberData) { - return ((NumberData) value).coerceToLong(); + return value.longValue(); } return UnsignedLong.valueOf(value.stringValue()).longValue(); @@ -1122,13 +1132,13 @@ public static long convertSoyValueToProtoUnsignedLong(SoyValue value) { @Nonnull @Keep public static SoyValue intToNumber(SoyValue value) { - return value instanceof NumberData ? FloatData.forValue(value.numberValue()) : value; + return value instanceof NumberData ? FloatData.forValue(value.floatValue()) : value; } @Nonnull @Keep public static SoyValue numberToInt(SoyValue value) { - return value instanceof NumberData ? IntegerData.forValue(value.coerceToLong()) : value; + return value instanceof NumberData ? IntegerData.forValue(value.longValue()) : value; } private JbcSrcRuntime() {} diff --git a/java/src/com/google/template/soy/shared/internal/Sanitizers.java b/java/src/com/google/template/soy/shared/internal/Sanitizers.java index 75b7576df7..47cb403867 100644 --- a/java/src/com/google/template/soy/shared/internal/Sanitizers.java +++ b/java/src/com/google/template/soy/shared/internal/Sanitizers.java @@ -495,7 +495,7 @@ public static String escapeJsValue(SoyValue value) { } 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() + " "; + return " " + value.floatValue() + " "; } else if (value instanceof BooleanData) { return " " + value.booleanValue() + " "; } else if (isSanitizedContentOfKind(value, SanitizedContent.ContentKind.JS)) { diff --git a/java/src/com/google/template/soy/shared/internal/SharedRuntime.java b/java/src/com/google/template/soy/shared/internal/SharedRuntime.java index f4b8bb658e..da93470534 100644 --- a/java/src/com/google/template/soy/shared/internal/SharedRuntime.java +++ b/java/src/com/google/template/soy/shared/internal/SharedRuntime.java @@ -72,7 +72,7 @@ public static boolean tripleEqual(SoyValue operand0, SoyValue operand1) { return operand0.booleanValue() == operand1.booleanValue(); } if (operand0 instanceof NumberData && operand1 instanceof NumberData) { - return operand0.numberValue() == operand1.numberValue(); + return operand0.floatValue() == operand1.floatValue(); } if (operand0 instanceof StringData && operand1 instanceof StringData) { return operand0.stringValue().equals(operand1.stringValue()); @@ -200,7 +200,7 @@ private static double toDoubleForNumericOp(SoyValue value) { if (value instanceof UndefinedData) { throw new SoyDataException("'undefined' cannot be coerced to float"); } - return value.numberValue(); + return value.floatValue(); } private static long toLongForNumericOp(SoyValue value) { @@ -220,7 +220,7 @@ private static long toLongForBitwiseOp(SoyValue value) { if (value.isNullish()) { return 0; } - return value.coerceToLong(); + return value.longValue(); } private static long toIntForBitwiseOp(SoyValue value) { @@ -263,7 +263,7 @@ public static boolean compareString(String string, SoyValue other) { if (other instanceof NumberData) { try { // Parse the string as a number. - return Double.parseDouble(string) == other.numberValue(); + return Double.parseDouble(string) == other.floatValue(); } catch (NumberFormatException nfe) { // Didn't parse as a number. return false; diff --git a/java/src/com/google/template/soy/sharedpasses/render/EvalVisitor.java b/java/src/com/google/template/soy/sharedpasses/render/EvalVisitor.java index 16c545316d..312454e69d 100644 --- a/java/src/com/google/template/soy/sharedpasses/render/EvalVisitor.java +++ b/java/src/com/google/template/soy/sharedpasses/render/EvalVisitor.java @@ -948,9 +948,9 @@ protected SoyValue visitFunctionNode(FunctionNode node) { + nonpluginFn.getName() + " function can't be used in templates compiled to Java"); case TO_NUMBER: - return FloatData.forValue(visit(node.getParam(0)).numberValue()); + return FloatData.forValue(visit(node.getParam(0)).floatValue()); case TO_INT: - return IntegerData.forValue(visit(node.getParam(0)).coerceToLong()); + return IntegerData.forValue(visit(node.getParam(0)).longValue()); case NUMBER_TO_INT: case INT_TO_NUMBER: SoyValue arg = visit(node.getParam(0)); @@ -958,8 +958,8 @@ protected SoyValue visitFunctionNode(FunctionNode node) { return arg; } return nonpluginFn == BuiltinFunction.NUMBER_TO_INT - ? IntegerData.forValue(arg.coerceToLong()) - : FloatData.forValue(arg.numberValue()); + ? IntegerData.forValue(arg.longValue()) + : FloatData.forValue(arg.floatValue()); case DEBUG_SOY_TEMPLATE_INFO: return BooleanData.forValue(debugSoyTemplateInfo); case VE_DATA: diff --git a/java/src/com/google/template/soy/sharedpasses/render/RenderVisitorAssistantForMsgs.java b/java/src/com/google/template/soy/sharedpasses/render/RenderVisitorAssistantForMsgs.java index 994fede1ee..289c995033 100644 --- a/java/src/com/google/template/soy/sharedpasses/render/RenderVisitorAssistantForMsgs.java +++ b/java/src/com/google/template/soy/sharedpasses/render/RenderVisitorAssistantForMsgs.java @@ -153,7 +153,7 @@ protected void visitMsgPluralNode(MsgPluralNode node) { ExprRootNode pluralExpr = node.getExpr(); double pluralValue; try { - pluralValue = master.evalForUseByAssistants(pluralExpr, node).numberValue(); + pluralValue = master.evalForUseByAssistants(pluralExpr, node).floatValue(); } catch (SoyDataException e) { throw RenderException.createWithSource( String.format( @@ -295,7 +295,7 @@ private void visitPart(SoyMsgPluralPartForRendering pluralPart) { double correctPluralValue; ExprRootNode pluralExpr = repPluralNode.getExpr(); try { - correctPluralValue = master.evalForUseByAssistants(pluralExpr, repPluralNode).numberValue(); + correctPluralValue = master.evalForUseByAssistants(pluralExpr, repPluralNode).floatValue(); } catch (SoyDataException e) { throw RenderException.createWithSource( String.format( diff --git a/java/src/com/google/template/soy/sharedpasses/render/TofuValueFactory.java b/java/src/com/google/template/soy/sharedpasses/render/TofuValueFactory.java index 671968302b..7863b89188 100644 --- a/java/src/com/google/template/soy/sharedpasses/render/TofuValueFactory.java +++ b/java/src/com/google/template/soy/sharedpasses/render/TofuValueFactory.java @@ -49,7 +49,6 @@ import com.google.template.soy.data.restricted.GbigintData; import com.google.template.soy.data.restricted.IntegerData; import com.google.template.soy.data.restricted.NullData; -import com.google.template.soy.data.restricted.NumberData; import com.google.template.soy.data.restricted.StringData; import com.google.template.soy.internal.proto.JavaQualifiedNames; import com.google.template.soy.plugin.internal.JavaPluginExecContext; @@ -344,9 +343,7 @@ static Object adaptValueToJava( } else if (isExternApi && type == Object.class) { return SoyValueUnconverter.unconvert(value); } else if (isExternApi && type == Number.class) { - return value instanceof NumberData - ? ((NumberData) value).javaNumberValue() - : value.numberValue(); + return value instanceof IntegerData ? value.longValue() : value.floatValue(); } else if (type.isInstance(value)) { return value; } @@ -359,9 +356,9 @@ static Object adaptValueToJava( } else if (primitiveType == long.class) { return value.longValue(); } else if (primitiveType == double.class) { - return value.numberValue(); + return value.floatValue(); } else if (primitiveType == float.class) { - return (float) value.numberValue(); + return (float) value.floatValue(); } else if (type == String.class) { return value.stringValue(); } else if (type == BigInteger.class) { diff --git a/java/tests/com/google/template/soy/data/restricted/PrimitiveDataTest.java b/java/tests/com/google/template/soy/data/restricted/PrimitiveDataTest.java index 9e9e1acde3..c6c58d2767 100644 --- a/java/tests/com/google/template/soy/data/restricted/PrimitiveDataTest.java +++ b/java/tests/com/google/template/soy/data/restricted/PrimitiveDataTest.java @@ -113,10 +113,10 @@ public void testNumberData() { FloatData fd0 = FloatData.forValue(0.0); FloatData fd1 = FloatData.forValue(2.0); - assertEquals(0.0, id0.toFloat(), 0.0); - assertEquals(2.0, id1.toFloat(), 0.0); - assertEquals(0.0, fd0.toFloat(), 0.0); - assertEquals(2.0, fd1.toFloat(), 0.0); + assertEquals(0.0, id0.floatValue(), 0.0); + assertEquals(2.0, id1.floatValue(), 0.0); + assertEquals(0.0, fd0.floatValue(), 0.0); + assertEquals(2.0, fd1.floatValue(), 0.0); assertTrue(id0.equals(fd0)); assertTrue(fd0.equals(id0)); diff --git a/java/tests/com/google/template/soy/plugin/java/restricted/testing/SoyJavaSourceFunctionTester.java b/java/tests/com/google/template/soy/plugin/java/restricted/testing/SoyJavaSourceFunctionTester.java index 119c2bb492..3992c000d3 100644 --- a/java/tests/com/google/template/soy/plugin/java/restricted/testing/SoyJavaSourceFunctionTester.java +++ b/java/tests/com/google/template/soy/plugin/java/restricted/testing/SoyJavaSourceFunctionTester.java @@ -238,8 +238,7 @@ private SoyExpression transform(Object value) { } else if (value instanceof Double) { return SoyExpression.forFloat(BytecodeUtils.constant(((Double) value).doubleValue())); } else if (value instanceof FloatData) { - return SoyExpression.forFloat(BytecodeUtils.constant(((FloatData) value).numberValue())) - .box(); + return SoyExpression.forFloat(BytecodeUtils.constant(((FloatData) value).floatValue())).box(); } else if (value instanceof String) { return SoyExpression.forString(BytecodeUtils.constant(((String) value))); } else if (value instanceof StringData) { diff --git a/java/tests/com/google/template/soy/shared/internal/SharedRuntimeTest.java b/java/tests/com/google/template/soy/shared/internal/SharedRuntimeTest.java index 543ce70b33..07561e998c 100644 --- a/java/tests/com/google/template/soy/shared/internal/SharedRuntimeTest.java +++ b/java/tests/com/google/template/soy/shared/internal/SharedRuntimeTest.java @@ -57,7 +57,7 @@ public void testPlus() { assertThat(plus(IntegerData.forValue(1), IntegerData.forValue(2)).integerValue()).isEqualTo(3); // N.B. coerced to float - assertThat(plus(FloatData.forValue(1), IntegerData.forValue(2)).numberValue()).isEqualTo(3.0); + assertThat(plus(FloatData.forValue(1), IntegerData.forValue(2)).floatValue()).isEqualTo(3.0); // coerced to string assertThat(plus(StringData.forValue("3"), IntegerData.forValue(2)).stringValue())