You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/02/23 21:35:59 UTC
[32/54] [partial] incubator-freemarker git commit: Unifying the
o.a.f.core and o.a.f.core.ast
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/AndExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/AndExpression.java b/src/main/java/org/apache/freemarker/core/ast/AndExpression.java
deleted file mode 100644
index 16a3cd3..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/AndExpression.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import org.apache.freemarker.core.TemplateException;
-
-final class AndExpression extends BooleanExpression {
-
- private final Expression lho;
- private final Expression rho;
-
- AndExpression(Expression lho, Expression rho) {
- this.lho = lho;
- this.rho = rho;
- }
-
- @Override
- boolean evalToBoolean(Environment env) throws TemplateException {
- return lho.evalToBoolean(env) && rho.evalToBoolean(env);
- }
-
- @Override
- public String getCanonicalForm() {
- return lho.getCanonicalForm() + " && " + rho.getCanonicalForm();
- }
-
- @Override
- String getNodeTypeSymbol() {
- return "&&";
- }
-
- @Override
- boolean isLiteral() {
- return constantValue != null || (lho.isLiteral() && rho.isLiteral());
- }
-
- @Override
- protected Expression deepCloneWithIdentifierReplaced_inner(
- String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) {
- return new AndExpression(
- lho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
- rho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState));
- }
-
- @Override
- int getParameterCount() {
- return 2;
- }
-
- @Override
- Object getParameterValue(int idx) {
- switch (idx) {
- case 0: return lho;
- case 1: return rho;
- default: throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- return ParameterRole.forBinaryOperatorOperand(idx);
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ArithmeticEngine.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/ArithmeticEngine.java b/src/main/java/org/apache/freemarker/core/ast/ArithmeticEngine.java
deleted file mode 100644
index 6b2d299..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/ArithmeticEngine.java
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.util._NumberUtil;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * Class to perform arithmetic operations.
- */
-
-public abstract class ArithmeticEngine {
-
- /**
- * Arithmetic engine that converts all numbers to {@link BigDecimal} and
- * then operates on them. This is FreeMarker's default arithmetic engine.
- */
- public static final BigDecimalEngine BIGDECIMAL_ENGINE = new BigDecimalEngine();
- /**
- * Arithmetic engine that uses (more-or-less) the widening conversions of
- * Java language to determine the type of result of operation, instead of
- * converting everything to BigDecimal up front.
- */
- public static final ConservativeEngine CONSERVATIVE_ENGINE = new ConservativeEngine();
-
- public abstract int compareNumbers(Number first, Number second) throws TemplateException;
- public abstract Number add(Number first, Number second) throws TemplateException;
- public abstract Number subtract(Number first, Number second) throws TemplateException;
- public abstract Number multiply(Number first, Number second) throws TemplateException;
- public abstract Number divide(Number first, Number second) throws TemplateException;
- public abstract Number modulus(Number first, Number second) throws TemplateException;
-
- /**
- * Should be able to parse all FTL numerical literals, Java Double toString results, and XML Schema numbers.
- * This means these should be parsed successfully, except if the arithmetical engine
- * couldn't support the resulting value anyway (such as NaN, infinite, even non-integers):
- * {@code -123.45}, {@code 1.5e3}, {@code 1.5E3}, {@code 0005}, {@code +0}, {@code -0}, {@code NaN},
- * {@code INF}, {@code -INF}, {@code Infinity}, {@code -Infinity}.
- */
- public abstract Number toNumber(String s);
-
- protected int minScale = 12;
- protected int maxScale = 12;
- protected int roundingPolicy = BigDecimal.ROUND_HALF_UP;
-
- /**
- * Sets the minimal scale to use when dividing BigDecimal numbers. Default
- * value is 12.
- */
- public void setMinScale(int minScale) {
- if (minScale < 0) {
- throw new IllegalArgumentException("minScale < 0");
- }
- this.minScale = minScale;
- }
-
- /**
- * Sets the maximal scale to use when multiplying BigDecimal numbers.
- * Default value is 100.
- */
- public void setMaxScale(int maxScale) {
- if (maxScale < minScale) {
- throw new IllegalArgumentException("maxScale < minScale");
- }
- this.maxScale = maxScale;
- }
-
- public void setRoundingPolicy(int roundingPolicy) {
- if (roundingPolicy != BigDecimal.ROUND_CEILING
- && roundingPolicy != BigDecimal.ROUND_DOWN
- && roundingPolicy != BigDecimal.ROUND_FLOOR
- && roundingPolicy != BigDecimal.ROUND_HALF_DOWN
- && roundingPolicy != BigDecimal.ROUND_HALF_EVEN
- && roundingPolicy != BigDecimal.ROUND_HALF_UP
- && roundingPolicy != BigDecimal.ROUND_UNNECESSARY
- && roundingPolicy != BigDecimal.ROUND_UP) {
- throw new IllegalArgumentException("invalid rounding policy");
- }
-
- this.roundingPolicy = roundingPolicy;
- }
-
- /**
- * This is the default arithmetic engine in FreeMarker. It converts every
- * number it receives into {@link BigDecimal}, then operates on these
- * converted {@link BigDecimal}s.
- */
- public static class BigDecimalEngine
- extends
- ArithmeticEngine {
- @Override
- public int compareNumbers(Number first, Number second) {
- // We try to find the result based on the sign (+/-/0) first, because:
- // - It's much faster than converting to BigDecial, and comparing to 0 is the most common comparison.
- // - It doesn't require any type conversions, and thus things like "Infinity > 0" won't fail.
- int firstSignum = _NumberUtil.getSignum(first);
- int secondSignum = _NumberUtil.getSignum(second);
- if (firstSignum != secondSignum) {
- return firstSignum < secondSignum ? -1 : (firstSignum > secondSignum ? 1 : 0);
- } else if (firstSignum == 0 && secondSignum == 0) {
- return 0;
- } else {
- BigDecimal left = toBigDecimal(first);
- BigDecimal right = toBigDecimal(second);
- return left.compareTo(right);
- }
- }
-
- @Override
- public Number add(Number first, Number second) {
- BigDecimal left = toBigDecimal(first);
- BigDecimal right = toBigDecimal(second);
- return left.add(right);
- }
-
- @Override
- public Number subtract(Number first, Number second) {
- BigDecimal left = toBigDecimal(first);
- BigDecimal right = toBigDecimal(second);
- return left.subtract(right);
- }
-
- @Override
- public Number multiply(Number first, Number second) {
- BigDecimal left = toBigDecimal(first);
- BigDecimal right = toBigDecimal(second);
- BigDecimal result = left.multiply(right);
- if (result.scale() > maxScale) {
- result = result.setScale(maxScale, roundingPolicy);
- }
- return result;
- }
-
- @Override
- public Number divide(Number first, Number second) {
- BigDecimal left = toBigDecimal(first);
- BigDecimal right = toBigDecimal(second);
- return divide(left, right);
- }
-
- @Override
- public Number modulus(Number first, Number second) {
- long left = first.longValue();
- long right = second.longValue();
- return Long.valueOf(left % right);
- }
-
- @Override
- public Number toNumber(String s) {
- return toBigDecimalOrDouble(s);
- }
-
- private BigDecimal divide(BigDecimal left, BigDecimal right) {
- int scale1 = left.scale();
- int scale2 = right.scale();
- int scale = Math.max(scale1, scale2);
- scale = Math.max(minScale, scale);
- return left.divide(right, scale, roundingPolicy);
- }
- }
-
- /**
- * An arithmetic engine that conservatively widens the operation arguments
- * to extent that they can hold the result of the operation. Widening
- * conversions occur in following situations:
- * <ul>
- * <li>byte and short are always widened to int (alike to Java language).</li>
- * <li>To preserve magnitude: when operands are of different types, the
- * result type is the type of the wider operand.</li>
- * <li>to avoid overflows: if add, subtract, or multiply would overflow on
- * integer types, the result is widened from int to long, or from long to
- * BigInteger.</li>
- * <li>to preserve fractional part: if a division of integer types would
- * have a fractional part, int and long are converted to double, and
- * BigInteger is converted to BigDecimal. An operation on a float and a
- * long results in a double. An operation on a float or double and a
- * BigInteger results in a BigDecimal.</li>
- * </ul>
- */
- public static class ConservativeEngine extends ArithmeticEngine {
- private static final int INTEGER = 0;
- private static final int LONG = 1;
- private static final int FLOAT = 2;
- private static final int DOUBLE = 3;
- private static final int BIGINTEGER = 4;
- private static final int BIGDECIMAL = 5;
-
- private static final Map classCodes = createClassCodesMap();
-
- @Override
- public int compareNumbers(Number first, Number second) throws TemplateException {
- switch(getCommonClassCode(first, second)) {
- case INTEGER: {
- int n1 = first.intValue();
- int n2 = second.intValue();
- return n1 < n2 ? -1 : (n1 == n2 ? 0 : 1);
- }
- case LONG: {
- long n1 = first.longValue();
- long n2 = second.longValue();
- return n1 < n2 ? -1 : (n1 == n2 ? 0 : 1);
- }
- case FLOAT: {
- float n1 = first.floatValue();
- float n2 = second.floatValue();
- return n1 < n2 ? -1 : (n1 == n2 ? 0 : 1);
- }
- case DOUBLE: {
- double n1 = first.doubleValue();
- double n2 = second.doubleValue();
- return n1 < n2 ? -1 : (n1 == n2 ? 0 : 1);
- }
- case BIGINTEGER: {
- BigInteger n1 = toBigInteger(first);
- BigInteger n2 = toBigInteger(second);
- return n1.compareTo(n2);
- }
- case BIGDECIMAL: {
- BigDecimal n1 = toBigDecimal(first);
- BigDecimal n2 = toBigDecimal(second);
- return n1.compareTo(n2);
- }
- }
- // Make the compiler happy. getCommonClassCode() is guaranteed to
- // return only above codes, or throw an exception.
- throw new Error();
- }
-
- @Override
- public Number add(Number first, Number second) throws TemplateException {
- switch(getCommonClassCode(first, second)) {
- case INTEGER: {
- int n1 = first.intValue();
- int n2 = second.intValue();
- int n = n1 + n2;
- return
- ((n ^ n1) < 0 && (n ^ n2) < 0) // overflow check
- ? Long.valueOf(((long) n1) + n2)
- : Integer.valueOf(n);
- }
- case LONG: {
- long n1 = first.longValue();
- long n2 = second.longValue();
- long n = n1 + n2;
- return
- ((n ^ n1) < 0 && (n ^ n2) < 0) // overflow check
- ? toBigInteger(first).add(toBigInteger(second))
- : Long.valueOf(n);
- }
- case FLOAT: {
- return Float.valueOf(first.floatValue() + second.floatValue());
- }
- case DOUBLE: {
- return Double.valueOf(first.doubleValue() + second.doubleValue());
- }
- case BIGINTEGER: {
- BigInteger n1 = toBigInteger(first);
- BigInteger n2 = toBigInteger(second);
- return n1.add(n2);
- }
- case BIGDECIMAL: {
- BigDecimal n1 = toBigDecimal(first);
- BigDecimal n2 = toBigDecimal(second);
- return n1.add(n2);
- }
- }
- // Make the compiler happy. getCommonClassCode() is guaranteed to
- // return only above codes, or throw an exception.
- throw new Error();
- }
-
- @Override
- public Number subtract(Number first, Number second) throws TemplateException {
- switch(getCommonClassCode(first, second)) {
- case INTEGER: {
- int n1 = first.intValue();
- int n2 = second.intValue();
- int n = n1 - n2;
- return
- ((n ^ n1) < 0 && (n ^ ~n2) < 0) // overflow check
- ? Long.valueOf(((long) n1) - n2)
- : Integer.valueOf(n);
- }
- case LONG: {
- long n1 = first.longValue();
- long n2 = second.longValue();
- long n = n1 - n2;
- return
- ((n ^ n1) < 0 && (n ^ ~n2) < 0) // overflow check
- ? toBigInteger(first).subtract(toBigInteger(second))
- : Long.valueOf(n);
- }
- case FLOAT: {
- return Float.valueOf(first.floatValue() - second.floatValue());
- }
- case DOUBLE: {
- return Double.valueOf(first.doubleValue() - second.doubleValue());
- }
- case BIGINTEGER: {
- BigInteger n1 = toBigInteger(first);
- BigInteger n2 = toBigInteger(second);
- return n1.subtract(n2);
- }
- case BIGDECIMAL: {
- BigDecimal n1 = toBigDecimal(first);
- BigDecimal n2 = toBigDecimal(second);
- return n1.subtract(n2);
- }
- }
- // Make the compiler happy. getCommonClassCode() is guaranteed to
- // return only above codes, or throw an exception.
- throw new Error();
- }
-
- @Override
- public Number multiply(Number first, Number second) throws TemplateException {
- switch(getCommonClassCode(first, second)) {
- case INTEGER: {
- int n1 = first.intValue();
- int n2 = second.intValue();
- int n = n1 * n2;
- return
- n1 == 0 || n / n1 == n2 // overflow check
- ? Integer.valueOf(n)
- : Long.valueOf(((long) n1) * n2);
- }
- case LONG: {
- long n1 = first.longValue();
- long n2 = second.longValue();
- long n = n1 * n2;
- return
- n1 == 0L || n / n1 == n2 // overflow check
- ? Long.valueOf(n)
- : toBigInteger(first).multiply(toBigInteger(second));
- }
- case FLOAT: {
- return Float.valueOf(first.floatValue() * second.floatValue());
- }
- case DOUBLE: {
- return Double.valueOf(first.doubleValue() * second.doubleValue());
- }
- case BIGINTEGER: {
- BigInteger n1 = toBigInteger(first);
- BigInteger n2 = toBigInteger(second);
- return n1.multiply(n2);
- }
- case BIGDECIMAL: {
- BigDecimal n1 = toBigDecimal(first);
- BigDecimal n2 = toBigDecimal(second);
- BigDecimal r = n1.multiply(n2);
- return r.scale() > maxScale ? r.setScale(maxScale, roundingPolicy) : r;
- }
- }
- // Make the compiler happy. getCommonClassCode() is guaranteed to
- // return only above codes, or throw an exception.
- throw new Error();
- }
-
- @Override
- public Number divide(Number first, Number second) throws TemplateException {
- switch(getCommonClassCode(first, second)) {
- case INTEGER: {
- int n1 = first.intValue();
- int n2 = second.intValue();
- if (n1 % n2 == 0) {
- return Integer.valueOf(n1 / n2);
- }
- return Double.valueOf(((double) n1) / n2);
- }
- case LONG: {
- long n1 = first.longValue();
- long n2 = second.longValue();
- if (n1 % n2 == 0) {
- return Long.valueOf(n1 / n2);
- }
- return Double.valueOf(((double) n1) / n2);
- }
- case FLOAT: {
- return Float.valueOf(first.floatValue() / second.floatValue());
- }
- case DOUBLE: {
- return Double.valueOf(first.doubleValue() / second.doubleValue());
- }
- case BIGINTEGER: {
- BigInteger n1 = toBigInteger(first);
- BigInteger n2 = toBigInteger(second);
- BigInteger[] divmod = n1.divideAndRemainder(n2);
- if (divmod[1].equals(BigInteger.ZERO)) {
- return divmod[0];
- } else {
- BigDecimal bd1 = new BigDecimal(n1);
- BigDecimal bd2 = new BigDecimal(n2);
- return bd1.divide(bd2, minScale, roundingPolicy);
- }
- }
- case BIGDECIMAL: {
- BigDecimal n1 = toBigDecimal(first);
- BigDecimal n2 = toBigDecimal(second);
- int scale1 = n1.scale();
- int scale2 = n2.scale();
- int scale = Math.max(scale1, scale2);
- scale = Math.max(minScale, scale);
- return n1.divide(n2, scale, roundingPolicy);
- }
- }
- // Make the compiler happy. getCommonClassCode() is guaranteed to
- // return only above codes, or throw an exception.
- throw new Error();
- }
-
- @Override
- public Number modulus(Number first, Number second) throws TemplateException {
- switch(getCommonClassCode(first, second)) {
- case INTEGER: {
- return Integer.valueOf(first.intValue() % second.intValue());
- }
- case LONG: {
- return Long.valueOf(first.longValue() % second.longValue());
- }
- case FLOAT: {
- return Float.valueOf(first.floatValue() % second.floatValue());
- }
- case DOUBLE: {
- return Double.valueOf(first.doubleValue() % second.doubleValue());
- }
- case BIGINTEGER: {
- BigInteger n1 = toBigInteger(first);
- BigInteger n2 = toBigInteger(second);
- return n1.mod(n2);
- }
- case BIGDECIMAL: {
- throw new _MiscTemplateException("Can't calculate remainder on BigDecimals");
- }
- }
- // Make the compiler happy. getCommonClassCode() is guaranteed to
- // return only above codes, or throw an exception.
- throw new BugException();
- }
-
- @Override
- public Number toNumber(String s) {
- Number n = toBigDecimalOrDouble(s);
- return n instanceof BigDecimal ? _NumberUtil.optimizeNumberRepresentation(n) : n;
- }
-
- private static Map createClassCodesMap() {
- Map map = new HashMap(17);
- Integer intcode = Integer.valueOf(INTEGER);
- map.put(Byte.class, intcode);
- map.put(Short.class, intcode);
- map.put(Integer.class, intcode);
- map.put(Long.class, Integer.valueOf(LONG));
- map.put(Float.class, Integer.valueOf(FLOAT));
- map.put(Double.class, Integer.valueOf(DOUBLE));
- map.put(BigInteger.class, Integer.valueOf(BIGINTEGER));
- map.put(BigDecimal.class, Integer.valueOf(BIGDECIMAL));
- return map;
- }
-
- private static int getClassCode(Number num) throws TemplateException {
- try {
- return ((Integer) classCodes.get(num.getClass())).intValue();
- } catch (NullPointerException e) {
- if (num == null) {
- throw new _MiscTemplateException("The Number object was null.");
- } else {
- throw new _MiscTemplateException("Unknown number type ", num.getClass().getName());
- }
- }
- }
-
- private static int getCommonClassCode(Number num1, Number num2) throws TemplateException {
- int c1 = getClassCode(num1);
- int c2 = getClassCode(num2);
- int c = c1 > c2 ? c1 : c2;
- // If BigInteger is combined with a Float or Double, the result is a
- // BigDecimal instead of BigInteger in order not to lose the
- // fractional parts. If Float is combined with Long, the result is a
- // Double instead of Float to preserve the bigger bit width.
- switch(c) {
- case FLOAT: {
- if ((c1 < c2 ? c1 : c2) == LONG) {
- return DOUBLE;
- }
- break;
- }
- case BIGINTEGER: {
- int min = c1 < c2 ? c1 : c2;
- if (min == DOUBLE || min == FLOAT) {
- return BIGDECIMAL;
- }
- break;
- }
- }
- return c;
- }
-
- private static BigInteger toBigInteger(Number num) {
- return num instanceof BigInteger ? (BigInteger) num : new BigInteger(num.toString());
- }
- }
-
- private static BigDecimal toBigDecimal(Number num) {
- try {
- return num instanceof BigDecimal ? (BigDecimal) num : new BigDecimal(num.toString());
- } catch (NumberFormatException e) {
- // The exception message is useless, so we add a new one:
- throw new NumberFormatException("Can't parse this as BigDecimal number: " + _StringUtil.jQuote(num));
- }
- }
-
- private static Number toBigDecimalOrDouble(String s) {
- if (s.length() > 2) {
- char c = s.charAt(0);
- if (c == 'I' && (s.equals("INF") || s.equals("Infinity"))) {
- return Double.valueOf(Double.POSITIVE_INFINITY);
- } else if (c == 'N' && s.equals("NaN")) {
- return Double.valueOf(Double.NaN);
- } else if (c == '-' && s.charAt(1) == 'I' && (s.equals("-INF") || s.equals("-Infinity"))) {
- return Double.valueOf(Double.NEGATIVE_INFINITY);
- }
- }
- return new BigDecimal(s);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ArithmeticExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/ArithmeticExpression.java b/src/main/java/org/apache/freemarker/core/ast/ArithmeticExpression.java
deleted file mode 100644
index 3b75418..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/ArithmeticExpression.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.impl.SimpleNumber;
-
-/**
- * An operator for arithmetic operations. Note that the + operator is in {@link AddConcatExpression}, because its
- * overloaded (does string concatenation and more).
- */
-final class ArithmeticExpression extends Expression {
-
- static final int TYPE_SUBSTRACTION = 0;
- static final int TYPE_MULTIPLICATION = 1;
- static final int TYPE_DIVISION = 2;
- static final int TYPE_MODULO = 3;
-
- private static final char[] OPERATOR_IMAGES = new char[] { '-', '*', '/', '%' };
-
- private final Expression lho;
- private final Expression rho;
- private final int operator;
-
- ArithmeticExpression(Expression lho, Expression rho, int operator) {
- this.lho = lho;
- this.rho = rho;
- this.operator = operator;
- }
-
- @Override
- TemplateModel _eval(Environment env) throws TemplateException {
- return _eval(env, this, lho.evalToNumber(env), operator, rho.evalToNumber(env));
- }
-
- static TemplateModel _eval(Environment env, TemplateObject parent, Number lhoNumber, int operator, Number rhoNumber)
- throws TemplateException, _MiscTemplateException {
- ArithmeticEngine ae = EvalUtil.getArithmeticEngine(env, parent);
- switch (operator) {
- case TYPE_SUBSTRACTION :
- return new SimpleNumber(ae.subtract(lhoNumber, rhoNumber));
- case TYPE_MULTIPLICATION :
- return new SimpleNumber(ae.multiply(lhoNumber, rhoNumber));
- case TYPE_DIVISION :
- return new SimpleNumber(ae.divide(lhoNumber, rhoNumber));
- case TYPE_MODULO :
- return new SimpleNumber(ae.modulus(lhoNumber, rhoNumber));
- default:
- if (parent instanceof Expression) {
- throw new _MiscTemplateException((Expression) parent,
- "Unknown operation: ", Integer.valueOf(operator));
- } else {
- throw new _MiscTemplateException("Unknown operation: ", Integer.valueOf(operator));
- }
- }
- }
-
- @Override
- public String getCanonicalForm() {
- return lho.getCanonicalForm() + ' ' + getOperatorSymbol(operator) + ' ' + rho.getCanonicalForm();
- }
-
- @Override
- String getNodeTypeSymbol() {
- return String.valueOf(getOperatorSymbol(operator));
- }
-
- static char getOperatorSymbol(int operator) {
- return OPERATOR_IMAGES[operator];
- }
-
- @Override
- boolean isLiteral() {
- return constantValue != null || (lho.isLiteral() && rho.isLiteral());
- }
-
- @Override
- protected Expression deepCloneWithIdentifierReplaced_inner(
- String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) {
- return new ArithmeticExpression(
- lho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
- rho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
- operator);
- }
-
- @Override
- int getParameterCount() {
- return 3;
- }
-
- @Override
- Object getParameterValue(int idx) {
- switch (idx) {
- case 0: return lho;
- case 1: return rho;
- case 2: return Integer.valueOf(operator);
- default: throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- switch (idx) {
- case 0: return ParameterRole.LEFT_HAND_OPERAND;
- case 1: return ParameterRole.RIGHT_HAND_OPERAND;
- case 2: return ParameterRole.AST_NODE_SUBTYPE;
- default: throw new IndexOutOfBoundsException();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/Assignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/Assignment.java b/src/main/java/org/apache/freemarker/core/ast/Assignment.java
deleted file mode 100644
index bed2088..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/Assignment.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.ast.FMParserConstants;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * An instruction that makes a single assignment, like [#local x=1].
- * This is also used as the child of {@link AssignmentInstruction}, if there are multiple assignments in the same tag,
- * like in [#local x=1 x=2].
- */
-final class Assignment extends TemplateElement {
-
- // These must not clash with ArithmeticExpression.TYPE_... constants:
- private static final int OPERATOR_TYPE_EQUALS = 0x10000;
- private static final int OPERATOR_TYPE_PLUS_EQUALS = 0x10001;
- private static final int OPERATOR_TYPE_PLUS_PLUS = 0x10002;
- private static final int OPERATOR_TYPE_MINUS_MINUS = 0x10003;
-
- private final int/*enum*/ scope;
- private final String variableName;
- private final int operatorType;
- private final Expression valueExp;
- private Expression namespaceExp;
-
- static final int NAMESPACE = 1;
- static final int LOCAL = 2;
- static final int GLOBAL = 3;
-
- private static final Number ONE = Integer.valueOf(1);
-
- /**
- * @param variableName the variable name to assign to.
- * @param valueExp the expression to assign.
- * @param scope the scope of the assignment, one of NAMESPACE, LOCAL, or GLOBAL
- */
- Assignment(String variableName,
- int operator,
- Expression valueExp,
- int scope) {
- this.scope = scope;
-
- this.variableName = variableName;
-
- if (operator == FMParserConstants.EQUALS) {
- operatorType = OPERATOR_TYPE_EQUALS;
- } else {
- switch (operator) {
- case FMParserConstants.PLUS_PLUS:
- operatorType = OPERATOR_TYPE_PLUS_PLUS;
- break;
- case FMParserConstants.MINUS_MINUS:
- operatorType = OPERATOR_TYPE_MINUS_MINUS;
- break;
- case FMParserConstants.PLUS_EQUALS:
- operatorType = OPERATOR_TYPE_PLUS_EQUALS;
- break;
- case FMParserConstants.MINUS_EQUALS:
- operatorType = ArithmeticExpression.TYPE_SUBSTRACTION;
- break;
- case FMParserConstants.TIMES_EQUALS:
- operatorType = ArithmeticExpression.TYPE_MULTIPLICATION;
- break;
- case FMParserConstants.DIV_EQUALS:
- operatorType = ArithmeticExpression.TYPE_DIVISION;
- break;
- case FMParserConstants.MOD_EQUALS:
- operatorType = ArithmeticExpression.TYPE_MODULO;
- break;
- default:
- throw new BugException();
- }
- }
-
- this.valueExp = valueExp;
- }
-
- void setNamespaceExp(Expression namespaceExp) {
- if (scope != NAMESPACE && namespaceExp != null) throw new BugException();
- this.namespaceExp = namespaceExp;
- }
-
- @Override
- TemplateElement[] accept(Environment env) throws TemplateException {
- final Environment.Namespace namespace;
- if (namespaceExp == null) {
- switch (scope) {
- case LOCAL:
- namespace = null;
- break;
- case GLOBAL:
- namespace = env.getGlobalNamespace();
- break;
- case NAMESPACE:
- namespace = env.getCurrentNamespace();
- break;
- default:
- throw new BugException("Unexpected scope type: " + scope);
- }
- } else {
- TemplateModel namespaceTM = namespaceExp.eval(env);
- try {
- namespace = (Environment.Namespace) namespaceTM;
- } catch (ClassCastException e) {
- throw new NonNamespaceException(namespaceExp, namespaceTM, env);
- }
- if (namespace == null) {
- throw InvalidReferenceException.getInstance(namespaceExp, env);
- }
- }
-
- TemplateModel value;
- if (operatorType == OPERATOR_TYPE_EQUALS) {
- value = valueExp.eval(env);
- valueExp.assertNonNull(value, env);
- } else {
- TemplateModel lhoValue;
- if (namespace == null) {
- lhoValue = env.getLocalVariable(variableName);
- } else {
- lhoValue = namespace.get(variableName);
- }
-
- if (operatorType == OPERATOR_TYPE_PLUS_EQUALS) { // Add or concat operation
- if (lhoValue == null) {
- throw InvalidReferenceException.getInstance(
- variableName, getOperatorTypeAsString(), env);
- }
-
- value = valueExp.eval(env);
- valueExp.assertNonNull(value, env);
- value = AddConcatExpression._eval(env, namespaceExp, null, lhoValue, valueExp, value);
- } else { // Numerical operation
- Number lhoNumber;
- if (lhoValue instanceof TemplateNumberModel) {
- lhoNumber = EvalUtil.modelToNumber((TemplateNumberModel) lhoValue, null);
- } else if (lhoValue == null) {
- throw InvalidReferenceException.getInstance(variableName, getOperatorTypeAsString(), env);
- } else {
- throw new NonNumericalException(variableName, lhoValue, null, env);
- }
-
- if (operatorType == OPERATOR_TYPE_PLUS_PLUS) {
- value = AddConcatExpression._evalOnNumbers(env, getParentElement(), lhoNumber, ONE);
- } else if (operatorType == OPERATOR_TYPE_MINUS_MINUS) {
- value = ArithmeticExpression._eval(
- env, getParentElement(), lhoNumber, ArithmeticExpression.TYPE_SUBSTRACTION, ONE);
- } else { // operatorType == ArithmeticExpression.TYPE_...
- Number rhoNumber = valueExp.evalToNumber(env);
- value = ArithmeticExpression._eval(env, this, lhoNumber, operatorType, rhoNumber);
- }
- }
- }
-
- if (namespace == null) {
- env.setLocalVariable(variableName, value);
- } else {
- namespace.put(variableName, value);
- }
- return null;
- }
-
- @Override
- protected String dump(boolean canonical) {
- StringBuilder buf = new StringBuilder();
- String dn = getParentElement() instanceof AssignmentInstruction ? null : getNodeTypeSymbol();
- if (dn != null) {
- if (canonical) buf.append("<");
- buf.append(dn);
- buf.append(' ');
- }
-
- buf.append(_StringUtil.toFTLTopLevelTragetIdentifier(variableName));
-
- if (valueExp != null) {
- buf.append(' ');
- }
- buf.append(getOperatorTypeAsString());
- if (valueExp != null) {
- buf.append(' ');
- buf.append(valueExp.getCanonicalForm());
- }
- if (dn != null) {
- if (namespaceExp != null) {
- buf.append(" in ");
- buf.append(namespaceExp.getCanonicalForm());
- }
- if (canonical) buf.append(">");
- }
- String result = buf.toString();
- return result;
- }
-
- @Override
- String getNodeTypeSymbol() {
- return getDirectiveName(scope);
- }
-
- static String getDirectiveName(int scope) {
- if (scope == Assignment.LOCAL) {
- return "#local";
- } else if (scope == Assignment.GLOBAL) {
- return "#global";
- } else if (scope == Assignment.NAMESPACE) {
- return "#assign";
- } else {
- return "#{unknown_assignment_type}";
- }
- }
-
- @Override
- int getParameterCount() {
- return 5;
- }
-
- @Override
- Object getParameterValue(int idx) {
- switch (idx) {
- case 0: return variableName;
- case 1: return getOperatorTypeAsString();
- case 2: return valueExp;
- case 3: return Integer.valueOf(scope);
- case 4: return namespaceExp;
- default: throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- switch (idx) {
- case 0: return ParameterRole.ASSIGNMENT_TARGET;
- case 1: return ParameterRole.ASSIGNMENT_OPERATOR;
- case 2: return ParameterRole.ASSIGNMENT_SOURCE;
- case 3: return ParameterRole.VARIABLE_SCOPE;
- case 4: return ParameterRole.NAMESPACE;
- default: throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-
- private String getOperatorTypeAsString() {
- if (operatorType == OPERATOR_TYPE_EQUALS) {
- return "=";
- } else if (operatorType == OPERATOR_TYPE_PLUS_EQUALS) {
- return "+=";
- } else if (operatorType == OPERATOR_TYPE_PLUS_PLUS) {
- return "++";
- } else if (operatorType == OPERATOR_TYPE_MINUS_MINUS) {
- return "--";
- } else {
- return ArithmeticExpression.getOperatorSymbol(operatorType) + "=";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/AssignmentInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/AssignmentInstruction.java b/src/main/java/org/apache/freemarker/core/ast/AssignmentInstruction.java
deleted file mode 100644
index caff0bb..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/AssignmentInstruction.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * An instruction that does multiple assignments, like [#local x=1 x=2].
- * Each assignment is represented by a {@link Assignment} child element.
- * If there's only one assignment, its usually just a {@link Assignment} without parent {@link AssignmentInstruction}.
- */
-final class AssignmentInstruction extends TemplateElement {
-
- private int scope;
- private Expression namespaceExp;
-
- AssignmentInstruction(int scope) {
- this.scope = scope;
- setChildBufferCapacity(1);
- }
-
- void addAssignment(Assignment assignment) {
- addChild(assignment);
- }
-
- void setNamespaceExp(Expression namespaceExp) {
- this.namespaceExp = namespaceExp;
- int ln = getChildCount();
- for (int i = 0; i < ln; i++) {
- ((Assignment) getChild(i)).setNamespaceExp(namespaceExp);
- }
- }
-
- @Override
- TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getChildBuffer();
- }
-
- @Override
- protected String dump(boolean canonical) {
- StringBuilder buf = new StringBuilder();
- if (canonical) buf.append('<');
- buf.append(Assignment.getDirectiveName(scope));
- if (canonical) {
- buf.append(' ');
- int ln = getChildCount();
- for (int i = 0; i < ln; i++) {
- if (i != 0) {
- buf.append(", ");
- }
- Assignment assignment = (Assignment) getChild(i);
- buf.append(assignment.getCanonicalForm());
- }
- } else {
- buf.append("-container");
- }
- if (namespaceExp != null) {
- buf.append(" in ");
- buf.append(namespaceExp.getCanonicalForm());
- }
- if (canonical) buf.append(">");
- return buf.toString();
- }
-
- @Override
- int getParameterCount() {
- return 2;
- }
-
- @Override
- Object getParameterValue(int idx) {
- switch (idx) {
- case 0: return Integer.valueOf(scope);
- case 1: return namespaceExp;
- default: return null;
- }
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- switch (idx) {
- case 0: return ParameterRole.VARIABLE_SCOPE;
- case 1: return ParameterRole.NAMESPACE;
- default: return null;
- }
- }
-
- @Override
- String getNodeTypeSymbol() {
- return Assignment.getDirectiveName(scope);
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/AttemptBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/AttemptBlock.java b/src/main/java/org/apache/freemarker/core/ast/AttemptBlock.java
deleted file mode 100644
index ee39820..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/AttemptBlock.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * Holder for the attempted section of the #attempt element and of the nested #recover element ({@link RecoveryBlock}).
- */
-final class AttemptBlock extends TemplateElement {
-
- private TemplateElement attemptedSection;
- private RecoveryBlock recoverySection;
-
- AttemptBlock(TemplateElements attemptedSectionChildren, RecoveryBlock recoverySection) {
- TemplateElement attemptedSection = attemptedSectionChildren.asSingleElement();
- this.attemptedSection = attemptedSection;
- this.recoverySection = recoverySection;
- setChildBufferCapacity(2);
- addChild(attemptedSection); // for backward compatibility
- addChild(recoverySection);
- }
-
- @Override
- TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- env.visitAttemptRecover(this, attemptedSection, recoverySection);
- return null;
- }
-
- @Override
- protected String dump(boolean canonical) {
- if (!canonical) {
- return getNodeTypeSymbol();
- } else {
- StringBuilder buf = new StringBuilder();
- buf.append("<").append(getNodeTypeSymbol()).append(">");
- buf.append(getChildrenCanonicalForm());
- buf.append("</").append(getNodeTypeSymbol()).append(">");
- return buf.toString();
- }
- }
-
- @Override
- int getParameterCount() {
- return 1;
- }
-
- @Override
- Object getParameterValue(int idx) {
- if (idx != 0) throw new IndexOutOfBoundsException();
- return recoverySection;
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- if (idx != 0) throw new IndexOutOfBoundsException();
- return ParameterRole.ERROR_HANDLER;
- }
-
- @Override
- String getNodeTypeSymbol() {
- return "#attempt";
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/AutoEscBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/AutoEscBlock.java b/src/main/java/org/apache/freemarker/core/ast/AutoEscBlock.java
deleted file mode 100644
index beb0bee..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/AutoEscBlock.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import java.io.IOException;
-
-import org.apache.freemarker.core.TemplateException;
-
-/**
- * An #autoEsc element
- */
-final class AutoEscBlock extends TemplateElement {
-
- AutoEscBlock(TemplateElements children) {
- setChildren(children);
- }
-
- @Override
- TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- return getChildBuffer();
- }
-
- @Override
- protected String dump(boolean canonical) {
- if (canonical) {
- return "<" + getNodeTypeSymbol() + "\">" + getChildrenCanonicalForm() + "</" + getNodeTypeSymbol() + ">";
- } else {
- return getNodeTypeSymbol();
- }
- }
-
- @Override
- String getNodeTypeSymbol() {
- return "#autoesc";
- }
-
- @Override
- int getParameterCount() {
- return 0;
- }
-
- @Override
- Object getParameterValue(int idx) {
- throw new IndexOutOfBoundsException();
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- throw new IndexOutOfBoundsException();
- }
-
- @Override
- boolean isIgnorable(boolean stripWhitespace) {
- return getChildCount() == 0;
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BackwardCompatibleTemplateNumberFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BackwardCompatibleTemplateNumberFormat.java b/src/main/java/org/apache/freemarker/core/ast/BackwardCompatibleTemplateNumberFormat.java
deleted file mode 100644
index 448dc26..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BackwardCompatibleTemplateNumberFormat.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-/**
- * Only exists for emulating pre-2.3.24-IcI {@code ?string} behavior.
- *
- * @since 2.3.24
- */
-abstract class BackwardCompatibleTemplateNumberFormat extends TemplateNumberFormat {
-
- abstract String format(Number number) throws UnformattableValueException;
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BlockAssignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BlockAssignment.java b/src/main/java/org/apache/freemarker/core/ast/BlockAssignment.java
deleted file mode 100644
index 20320c2..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BlockAssignment.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-import org.apache.freemarker.core.model.TemplateTransformModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * Like [#local x]...[/#local].
- */
-final class BlockAssignment extends TemplateElement {
-
- private final String varName;
- private final Expression namespaceExp;
- private final int scope;
- private final MarkupOutputFormat<?> markupOutputFormat;
-
- BlockAssignment(TemplateElements children, String varName, int scope, Expression namespaceExp, MarkupOutputFormat<?> markupOutputFormat) {
- setChildren(children);
- this.varName = varName;
- this.namespaceExp = namespaceExp;
- this.scope = scope;
- this.markupOutputFormat = markupOutputFormat;
- }
-
- @Override
- TemplateElement[] accept(Environment env) throws TemplateException, IOException {
- TemplateElement[] children = getChildBuffer();
- if (children != null) {
- env.visitAndTransform(children, new CaptureOutput(env), null);
- } else {
- TemplateModel value = capturedStringToModel("");
- if (namespaceExp != null) {
- Environment.Namespace ns = (Environment.Namespace) namespaceExp.eval(env);
- ns.put(varName, value);
- } else if (scope == Assignment.NAMESPACE) {
- env.setVariable(varName, value);
- } else if (scope == Assignment.GLOBAL) {
- env.setGlobalVariable(varName, value);
- } else if (scope == Assignment.LOCAL) {
- env.setLocalVariable(varName, value);
- }
- }
- return null;
- }
-
- private TemplateModel capturedStringToModel(String s) throws TemplateModelException {
- return markupOutputFormat == null ? new SimpleScalar(s) : markupOutputFormat.fromMarkup(s);
- }
-
- private class CaptureOutput implements TemplateTransformModel {
- private final Environment env;
- private final Environment.Namespace fnsModel;
-
- CaptureOutput(Environment env) throws TemplateException {
- this.env = env;
- TemplateModel nsModel = null;
- if (namespaceExp != null) {
- nsModel = namespaceExp.eval(env);
- if (!(nsModel instanceof Environment.Namespace)) {
- throw new NonNamespaceException(namespaceExp, nsModel, env);
- }
- }
- fnsModel = (Environment.Namespace ) nsModel;
- }
-
- @Override
- public Writer getWriter(Writer out, Map args) {
- return new StringWriter() {
- @Override
- public void close() throws IOException {
- TemplateModel result;
- try {
- result = capturedStringToModel(toString());
- } catch (TemplateModelException e) {
- // [Java 1.6] e to cause
- throw new IOException("Failed to create FTL value from captured string: " + e);
- }
- switch(scope) {
- case Assignment.NAMESPACE: {
- if (fnsModel != null) {
- fnsModel.put(varName, result);
- } else {
- env.setVariable(varName, result);
- }
- break;
- }
- case Assignment.LOCAL: {
- env.setLocalVariable(varName, result);
- break;
- }
- case Assignment.GLOBAL: {
- env.setGlobalVariable(varName, result);
- break;
- }
- }
- }
- };
- }
- }
-
- @Override
- protected String dump(boolean canonical) {
- StringBuilder sb = new StringBuilder();
- if (canonical) sb.append("<");
- sb.append(getNodeTypeSymbol());
- sb.append(' ');
- sb.append(varName);
- if (namespaceExp != null) {
- sb.append(" in ");
- sb.append(namespaceExp.getCanonicalForm());
- }
- if (canonical) {
- sb.append('>');
- sb.append(getChildrenCanonicalForm());
- sb.append("</");
- sb.append(getNodeTypeSymbol());
- sb.append('>');
- } else {
- sb.append(" = .nested_output");
- }
- return sb.toString();
- }
-
- @Override
- String getNodeTypeSymbol() {
- return Assignment.getDirectiveName(scope);
- }
-
- @Override
- int getParameterCount() {
- return 3;
- }
-
- @Override
- Object getParameterValue(int idx) {
- switch (idx) {
- case 0: return varName;
- case 1: return Integer.valueOf(scope);
- case 2: return namespaceExp;
- default: throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- switch (idx) {
- case 0: return ParameterRole.ASSIGNMENT_TARGET;
- case 1: return ParameterRole.VARIABLE_SCOPE;
- case 2: return ParameterRole.NAMESPACE;
- default: throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BodyInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BodyInstruction.java b/src/main/java/org/apache/freemarker/core/ast/BodyInstruction.java
deleted file mode 100644
index 548f9fd..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BodyInstruction.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-
-/**
- * An instruction that processes the nested block within a macro instruction.
- */
-final class BodyInstruction extends TemplateElement {
-
-
- private List bodyParameters;
-
-
- BodyInstruction(List bodyParameters) {
- this.bodyParameters = bodyParameters;
- }
-
- List getBodyParameters() {
- return bodyParameters;
- }
-
- /**
- * There is actually a subtle but essential point in the code below.
- * A macro operates in the context in which it's defined. However,
- * a nested block within a macro instruction is defined in the
- * context in which the macro was invoked. So, we actually need to
- * temporarily switch the namespace and macro context back to
- * what it was before macro invocation to implement this properly.
- * I (JR) realized this thanks to some incisive comments from Daniel Dekany.
- */
- @Override
- TemplateElement[] accept(Environment env) throws IOException, TemplateException {
- Context bodyContext = new Context(env);
- env.invokeNestedContent(bodyContext);
- return null;
- }
-
- @Override
- protected String dump(boolean canonical) {
- StringBuilder sb = new StringBuilder();
- if (canonical) sb.append('<');
- sb.append(getNodeTypeSymbol());
- if (bodyParameters != null) {
- for (int i = 0; i < bodyParameters.size(); i++) {
- sb.append(' ');
- sb.append(((Expression) bodyParameters.get(i)).getCanonicalForm());
- }
- }
- if (canonical) sb.append('>');
- return sb.toString();
- }
-
- @Override
- String getNodeTypeSymbol() {
- return "#nested";
- }
-
- @Override
- int getParameterCount() {
- return bodyParameters != null ? bodyParameters.size() : 0;
- }
-
- @Override
- Object getParameterValue(int idx) {
- checkIndex(idx);
- return bodyParameters.get(idx);
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- checkIndex(idx);
- return ParameterRole.PASSED_VALUE;
- }
-
- private void checkIndex(int idx) {
- if (bodyParameters == null || idx >= bodyParameters.size()) {
- throw new IndexOutOfBoundsException();
- }
- }
-
- /*
- boolean heedsOpeningWhitespace() {
- return true;
- }
-
- boolean heedsTrailingWhitespace() {
- return true;
- }
- */
-
- @Override
- boolean isShownInStackTrace() {
- return true;
- }
-
- class Context implements LocalContext {
- Macro.Context invokingMacroContext;
- Environment.Namespace bodyVars;
-
- Context(Environment env) throws TemplateException {
- invokingMacroContext = env.getCurrentMacroContext();
- List bodyParameterNames = invokingMacroContext.nestedContentParameterNames;
- if (bodyParameters != null) {
- for (int i = 0; i < bodyParameters.size(); i++) {
- Expression exp = (Expression) bodyParameters.get(i);
- TemplateModel tm = exp.eval(env);
- if (bodyParameterNames != null && i < bodyParameterNames.size()) {
- String bodyParameterName = (String) bodyParameterNames.get(i);
- if (bodyVars == null) {
- bodyVars = env.new Namespace();
- }
- bodyVars.put(bodyParameterName, tm);
- }
- }
- }
- }
-
- @Override
- public TemplateModel getLocalVariable(String name) throws TemplateModelException {
- return bodyVars == null ? null : bodyVars.get(name);
- }
-
- @Override
- public Collection getLocalVariableNames() {
- List bodyParameterNames = invokingMacroContext.nestedContentParameterNames;
- return bodyParameterNames == null ? Collections.EMPTY_LIST : bodyParameterNames;
- }
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BooleanExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BooleanExpression.java b/src/main/java/org/apache/freemarker/core/ast/BooleanExpression.java
deleted file mode 100644
index 08e1dc7..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BooleanExpression.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-abstract class BooleanExpression extends Expression {
-
- @Override
- TemplateModel _eval(Environment env) throws TemplateException {
- return evalToBoolean(env) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BooleanLiteral.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BooleanLiteral.java b/src/main/java/org/apache/freemarker/core/ast/BooleanLiteral.java
deleted file mode 100644
index 82cfb8f..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BooleanLiteral.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-final class BooleanLiteral extends Expression {
-
- private final boolean val;
-
- public BooleanLiteral(boolean val) {
- this.val = val;
- }
-
- static TemplateBooleanModel getTemplateModel(boolean b) {
- return b? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
- }
-
- @Override
- boolean evalToBoolean(Environment env) {
- return val;
- }
-
- @Override
- public String getCanonicalForm() {
- return val ? MiscUtil.C_TRUE : MiscUtil.C_FALSE;
- }
-
- @Override
- String getNodeTypeSymbol() {
- return getCanonicalForm();
- }
-
- @Override
- public String toString() {
- return val ? MiscUtil.C_TRUE : MiscUtil.C_FALSE;
- }
-
- @Override
- TemplateModel _eval(Environment env) {
- return val ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
- }
-
- @Override
- boolean isLiteral() {
- return true;
- }
-
- @Override
- protected Expression deepCloneWithIdentifierReplaced_inner(
- String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) {
- return new BooleanLiteral(val);
- }
-
- @Override
- int getParameterCount() {
- return 0;
- }
-
- @Override
- Object getParameterValue(int idx) {
- throw new IndexOutOfBoundsException();
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- throw new IndexOutOfBoundsException();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BoundedRangeModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BoundedRangeModel.java b/src/main/java/org/apache/freemarker/core/ast/BoundedRangeModel.java
deleted file mode 100644
index 88c1d0b..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BoundedRangeModel.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-
-/**
- * A range between two integers (maybe 0 long).
- */
-final class BoundedRangeModel extends RangeModel {
-
- private final int step, size;
- private final boolean rightAdaptive;
- private final boolean affectedByStringSlicingBug;
-
- /**
- * @param inclusiveEnd Tells if the {@code end} index is part of the range.
- * @param rightAdaptive Tells if the right end of the range adapts to the size of the sliced value, if otherwise
- * it would be bigger than that.
- */
- BoundedRangeModel(int begin, int end, boolean inclusiveEnd, boolean rightAdaptive) {
- super(begin);
- step = begin <= end ? 1 : -1;
- size = Math.abs(end - begin) + (inclusiveEnd ? 1 : 0);
- this.rightAdaptive = rightAdaptive;
- affectedByStringSlicingBug = inclusiveEnd;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- int getStep() {
- return step;
- }
-
- @Override
- boolean isRightUnbounded() {
- return false;
- }
-
- @Override
- boolean isRightAdaptive() {
- return rightAdaptive;
- }
-
- @Override
- boolean isAffactedByStringSlicingBug() {
- return affectedByStringSlicingBug;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BreakInstruction.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BreakInstruction.java b/src/main/java/org/apache/freemarker/core/ast/BreakInstruction.java
deleted file mode 100644
index 67a770e..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BreakInstruction.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-/**
- * Represents a <break> instruction to break out of a loop.
- */
-final class BreakInstruction extends TemplateElement {
-
- @Override
- TemplateElement[] accept(Environment env) {
- throw Break.INSTANCE;
- }
-
- @Override
- protected String dump(boolean canonical) {
- return canonical ? "<" + getNodeTypeSymbol() + "/>" : getNodeTypeSymbol();
- }
-
- @Override
- String getNodeTypeSymbol() {
- return "#break";
- }
-
- @Override
- int getParameterCount() {
- return 0;
- }
-
- @Override
- Object getParameterValue(int idx) {
- throw new IndexOutOfBoundsException();
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- throw new IndexOutOfBoundsException();
- }
-
- static class Break extends RuntimeException {
- static final Break INSTANCE = new Break();
- private Break() {
- }
- }
-
- @Override
- boolean isNestedBlockRepeater() {
- return false;
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/BugException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/ast/BugException.java b/src/main/java/org/apache/freemarker/core/ast/BugException.java
deleted file mode 100644
index 9850b74..0000000
--- a/src/main/java/org/apache/freemarker/core/ast/BugException.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.freemarker.core.ast;
-
-/**
- * An unexpected state was reached that is certainly caused by a bug in FreeMarker.
- *
- * @since 2.3.21
- */
-public class BugException extends RuntimeException {
-
- private static final String COMMON_MESSAGE
- = "A bug was detected in FreeMarker; please report it with stack-trace";
-
- public BugException() {
- this((Throwable) null);
- }
-
- public BugException(String message) {
- this(message, null);
- }
-
- public BugException(Throwable cause) {
- super(COMMON_MESSAGE, cause);
- }
-
- public BugException(String message, Throwable cause) {
- super(COMMON_MESSAGE + ": " + message, cause);
- }
-
- public BugException(int value) {
- this(String.valueOf(value));
- }
-
-}