/*
 * Copyright 1994-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.tools.tree;

import sun.tools.java.*;
import sun.tools.asm.Assembler;

/**
 * WARNING: The contents of this source file are not part of any
 * supported API.  Code that depends on them does so at its own risk:
 * they are subject to change or removal without notice.
 */
public
class AddExpression extends BinaryArithmeticExpression {
    /**
     * constructor
     */
    public AddExpression(long where, Expression left, Expression right) {
        super(ADD, where, left, right);
    }

    /**
     * Select the type
     */
    void selectType(Environment env, Context ctx, int tm) {
        if ((left.type == Type.tString) && !right.type.isType(TC_VOID)) {
            type = Type.tString;
            return;
        } else if ((right.type == Type.tString) && !left.type.isType(TC_VOID)) {
            type = Type.tString;
            return;
        }
        super.selectType(env, ctx, tm);
    }

    public boolean isNonNull() {
        // an addition expression cannot yield a null reference as a result
        return true;
    }

    /**
     * Evaluate
     */
    Expression eval(int a, int b) {
        return new IntExpression(where, a + b);
    }
    Expression eval(long a, long b) {
        return new LongExpression(where, a + b);
    }
    Expression eval(float a, float b) {
        return new FloatExpression(where, a + b);
    }
    Expression eval(double a, double b) {
        return new DoubleExpression(where, a + b);
    }
    Expression eval(String a, String b) {
        return new StringExpression(where, a + b);
    }

    /**
     * Inline the value of an AddExpression.  If this AddExpression
     * represents a concatenation of compile-time constant strings,
     * dispatch to the special method inlineValueSB, which handles
     * the inlining more efficiently.
     */
    public Expression inlineValue(Environment env, Context ctx) {
        if (type == Type.tString && isConstant()) {
            StringBuffer buffer = inlineValueSB(env, ctx, new StringBuffer());
            if (buffer != null) {
                // We were able to evaluate the String concatenation.
                return new StringExpression(where, buffer.toString());
            }
        }
        // For some reason inlinValueSB() failed to produce a value.
        // Use the older, less efficient, inlining mechanism.
        return super.inlineValue(env, ctx);
    }

    /**
     * Attempt to evaluate this expression.  If this expression
     * yields a value, append it to the StringBuffer `buffer'.
     * If this expression cannot be evaluated at this time (for
     * example if it contains a division by zero, a non-constant
     * subexpression, or a subexpression which "refuses" to evaluate)
     * then return `null' to indicate failure.
     *
     * It is anticipated that this method will be called to evaluate
     * concatenations of compile-time constant strings.  The call
     * originates from AddExpression#inlineValue().
     *
     * This method does not use associativity to good effect in
     * folding string concatenations.  This is room for improvement.
     *
     * -------------
     *
     * A bit of history: this method was added because an
     * expression like...
     *
     *     "a" + "b" + "c" + "d"
     *
     * ...was evaluated at compile-time as...
     *
     *     (new StringBuffer((new StringBuffer("a")).append("b").toString())).
     *      append((new StringBuffer("c")).append("d").toString()).toString()
     *
     * Alex Garthwaite, in profiling the memory allocation of the
     * compiler, noticed this and suggested that the method inlineValueSB()
     * be added to evaluate constant string concatenations in a more
     * efficient manner.  The compiler now builds the string in a
     * top-down fashion, by accumulating the result in a StringBuffer
     * which is allocated once and passed in as a parameter.  The new
     * evaluation scheme is equivalent to...
     *
     *     (new StringBuffer("a")).append("b").append("c").append("d")
     *                 .toString()
     *
     * ...which is more efficient.  Since then, the code has been modified
     * to fix certain problems.  Now, for example, it can return `null'
     * when it encounters a concatenation which it is not able to
     * evaluate.
     *
     * See also Expression#inlineValueSB() and ExprExpression#inlineValueSB().
     */
    protected StringBuffer inlineValueSB(Environment env,
                                         Context ctx,
                                         StringBuffer buffer) {
        if (type != Type.tString) {
            // This isn't a concatenation.  It is actually an addition
            // of some sort.  Call the generic inlineValueSB()
            return super.inlineValueSB(env, ctx, buffer);
        }

        buffer = left.inlineValueSB(env, ctx, buffer);
        if (buffer != null) {
            buffer = right.inlineValueSB(env, ctx, buffer);
        }
        return buffer;
    }

    /**
     * Simplify
     */
    Expression simplify() {
        if (!type.isType(TC_CLASS)) {
            // Can't simplify floating point add because of -0.0 strangeness
            if (type.inMask(TM_INTEGER)) {
                if (left.equals(0)) {
                    return right;
                }
                if (right.equals(0)) {
                    return left;
                }
            }
        } else if (right.type.isType(TC_NULL)) {
            right = new StringExpression(right.where, "null");
        } else if (left.type.isType(TC_NULL)) {
            left = new StringExpression(left.where, "null");
        }
        return this;
    }

    /**
     * The cost of inlining this expression
     */
    public int costInline(int thresh, Environment env, Context ctx) {
        return (type.isType(TC_CLASS) ? 12 : 1)
            + left.costInline(thresh, env, ctx)
            + right.costInline(thresh, env, ctx);
    }

    /**
     * Code
     */
    void codeOperation(Environment env, Context ctx, Assembler asm) {
        asm.add(where, opc_iadd + type.getTypeCodeOffset());
    }

    /**
     * Convert this expression to a string and append it to the string
     * buffer on the top of the stack.
     * If the needBuffer argument is true, the string buffer needs to be
     * created, initialized, and pushed on the stack, first.
     */
    void codeAppend(Environment env, Context ctx, Assembler asm,
                    ClassDeclaration sbClass, boolean needBuffer)
        throws ClassNotFound, AmbiguousMember {
        if (type.isType(TC_CLASS)) {
            left.codeAppend(env, ctx, asm, sbClass, needBuffer);
            right.codeAppend(env, ctx, asm, sbClass, false);
        } else {
            super.codeAppend(env, ctx, asm, sbClass, needBuffer);
        }
    }

    public void codeValue(Environment env, Context ctx, Assembler asm) {
        if (type.isType(TC_CLASS)) {
            try {
                // optimize (""+foo) or (foo+"") to String.valueOf(foo)
                if (left.equals("")) {
                    right.codeValue(env, ctx, asm);
                    right.ensureString(env, ctx, asm);
                    return;
                }
                if (right.equals("")) {
                    left.codeValue(env, ctx, asm);
                    left.ensureString(env, ctx, asm);
                    return;
                }

                ClassDeclaration sbClass =
                    env.getClassDeclaration(idJavaLangStringBuffer);
                ClassDefinition sourceClass = ctx.field.getClassDefinition();
                // Create the string buffer and append to it.
                codeAppend(env, ctx, asm, sbClass, true);
                // Convert the string buffer to a string
                MemberDefinition f =
                    sbClass.getClassDefinition(env).matchMethod(env,
                                                                sourceClass,
                                                                idToString);
                asm.add(where, opc_invokevirtual, f);
            } catch (ClassNotFound e) {
                throw new CompilerError(e);
            } catch (AmbiguousMember e) {
                throw new CompilerError(e);
            }
        } else {
            super.codeValue(env, ctx, asm);
        }
    }
}
