1/*
2 * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.tools.tree;
27
28import sun.tools.java.*;
29import java.io.PrintStream;
30import java.util.Hashtable;
31
32/**
33 * WARNING: The contents of this source file are not part of any
34 * supported API.  Code that depends on them does so at its own risk:
35 * they are subject to change or removal without notice.
36 */
37public
38class UnaryExpression extends Expression {
39    Expression right;
40
41    /**
42     * Constructor
43     */
44    UnaryExpression(int op, long where, Type type, Expression right) {
45        super(op, where, type);
46        this.right = right;
47    }
48
49    /**
50     * Order the expression based on precedence
51     */
52    public Expression order() {
53        if (precedence() > right.precedence()) {
54            UnaryExpression e = (UnaryExpression)right;
55            right = e.right;
56            e.right = order();
57            return e;
58        }
59        return this;
60    }
61
62    /**
63     * Select the type of the expression
64     */
65    void selectType(Environment env, Context ctx, int tm) {
66        throw new CompilerError("selectType: " + opNames[op]);
67    }
68
69    /**
70     * Check a unary expression
71     */
72    public Vset checkValue(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp) {
73        vset = right.checkValue(env, ctx, vset, exp);
74
75        int tm = right.type.getTypeMask();
76        selectType(env, ctx, tm);
77        if (((tm & TM_ERROR) == 0) && type.isType(TC_ERROR)) {
78            env.error(where, "invalid.arg", opNames[op]);
79        }
80        return vset;
81    }
82
83    /**
84     * Check if constant
85     */
86    public boolean isConstant() {
87        switch (op) {
88        case POS:
89        case NEG:
90        case BITNOT:
91        case NOT:
92        case EXPR:
93        case CONVERT: // generated inside of CastExpression
94            return right.isConstant();
95        }
96        return false;
97    }
98
99    /**
100     * Evaluate
101     */
102    Expression eval(int a) {
103        return this;
104    }
105    Expression eval(long a) {
106        return this;
107    }
108    Expression eval(float a) {
109        return this;
110    }
111    Expression eval(double a) {
112        return this;
113    }
114    Expression eval(boolean a) {
115        return this;
116    }
117    Expression eval(String a) {
118        return this;
119    }
120    Expression eval() {
121        switch (right.op) {
122          case BYTEVAL:
123          case CHARVAL:
124          case SHORTVAL:
125          case INTVAL:
126            return eval(((IntegerExpression)right).value);
127          case LONGVAL:
128            return eval(((LongExpression)right).value);
129          case FLOATVAL:
130            return eval(((FloatExpression)right).value);
131          case DOUBLEVAL:
132            return eval(((DoubleExpression)right).value);
133          case BOOLEANVAL:
134            return eval(((BooleanExpression)right).value);
135          case STRINGVAL:
136            return eval(((StringExpression)right).value);
137        }
138        return this;
139    }
140
141    /**
142     * Inline
143     */
144    public Expression inline(Environment env, Context ctx) {
145        return right.inline(env, ctx);
146    }
147    public Expression inlineValue(Environment env, Context ctx) {
148        right = right.inlineValue(env, ctx);
149        try {
150            return eval().simplify();
151        } catch (ArithmeticException e) {
152            // Got rid of this error message.  It isn't illegal to
153            // have a program which does a constant division by
154            // zero.  We return `this' to make the compiler to
155            // generate code here.
156            // (bugs 4019304, 4089107).
157            //
158            // I am not positive that this catch is ever reached.
159            //
160            // env.error(where, "arithmetic.exception");
161            return this;
162        }
163    }
164
165    /**
166     * Create a copy of the expression for method inlining
167     */
168    public Expression copyInline(Context ctx) {
169        UnaryExpression e = (UnaryExpression)clone();
170        if (right != null) {
171            e.right = right.copyInline(ctx);
172        }
173        return e;
174    }
175
176    /**
177     * The cost of inlining this expression
178     */
179    public int costInline(int thresh, Environment env, Context ctx) {
180        return 1 + right.costInline(thresh, env, ctx);
181    }
182
183    /**
184     * Print
185     */
186    public void print(PrintStream out) {
187        out.print("(" + opNames[op] + " ");
188        right.print(out);
189        out.print(")");
190    }
191}
192