001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: UnaryOpExpr.java 468650 2006-10-28 07:03:30Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.compiler;
023    
024    import org.apache.bcel.generic.InstructionList;
025    import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
026    import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
027    import org.apache.xalan.xsltc.compiler.util.MethodType;
028    import org.apache.xalan.xsltc.compiler.util.Type;
029    import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
030    
031    /**
032     * @author Jacek Ambroziak
033     * @author Santiago Pericas-Geertsen
034     */
035    final class UnaryOpExpr extends Expression {
036        private Expression _left;
037            
038        public UnaryOpExpr(Expression left) {
039            (_left = left).setParent(this);
040        }
041    
042        /**
043         * Returns true if this expressions contains a call to position(). This is
044         * needed for context changes in node steps containing multiple predicates.
045         */
046        public boolean hasPositionCall() {
047            return(_left.hasPositionCall());
048        }
049    
050        /**
051         * Returns true if this expressions contains a call to last()
052         */
053        public boolean hasLastCall() {
054                return(_left.hasLastCall());
055        }
056        
057        public void setParser(Parser parser) {
058            super.setParser(parser);
059            _left.setParser(parser);
060        }
061        
062        public Type typeCheck(SymbolTable stable) throws TypeCheckError {
063            final Type tleft = _left.typeCheck(stable); 
064            final MethodType ptype = lookupPrimop(stable, "u-",
065                                                  new MethodType(Type.Void,
066                                                                 tleft)); 
067            
068            if (ptype != null) {
069                final Type arg1 = (Type) ptype.argsType().elementAt(0);
070                if (!arg1.identicalTo(tleft)) {
071                    _left = new CastExpr(_left, arg1);
072                }
073                return _type = ptype.resultType();
074            }
075    
076            throw new TypeCheckError(this);
077        }
078    
079        public String toString() {
080            return "u-" + '(' + _left + ')';
081        }
082    
083        public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
084            InstructionList il = methodGen.getInstructionList();
085            _left.translate(classGen, methodGen);
086            il.append(_type.NEG());
087        }
088    }
089