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: ParameterRef.java 528589 2007-04-13 18:50:56Z zongaro $
020     */
021    
022    package org.apache.xalan.xsltc.compiler;
023    
024    import org.apache.bcel.generic.CHECKCAST;
025    import org.apache.bcel.generic.ConstantPoolGen;
026    import org.apache.bcel.generic.GETFIELD;
027    import org.apache.bcel.generic.INVOKEINTERFACE;
028    import org.apache.bcel.generic.InstructionList;
029    import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
030    import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
031    import org.apache.xalan.xsltc.compiler.util.NodeSetType;
032    import org.apache.xalan.xsltc.runtime.BasisLibrary;
033    
034    /**
035     * @author Jacek Ambroziak
036     * @author Santiago Pericas-Geertsen
037     * @author Morten Jorgensen
038     * @author Erwin Bolwidt <ejb@klomp.org>
039     */
040    final class ParameterRef extends VariableRefBase {
041    
042        /**
043         * Name of param being referenced.
044         */
045        QName _name = null;
046        
047        public ParameterRef(Param param) {
048            super(param);
049            _name = param._name;
050            
051        }
052    
053        public String toString() {
054            return "parameter-ref("+_variable.getName()+'/'+_variable.getType()+')';
055        }
056    
057        public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
058            final ConstantPoolGen cpg = classGen.getConstantPool();
059            final InstructionList il = methodGen.getInstructionList();
060    
061            /*
062             * To fix bug 24518 related to setting parameters of the form
063             * {namespaceuri}localName, which will get mapped to an instance 
064             * variable in the class.
065             */
066            final String name = BasisLibrary.mapQNameToJavaName (_name.toString());
067            final String signature = _type.toSignature();
068    
069            if (_variable.isLocal()) {
070                if (classGen.isExternal()) {
071                    Closure variableClosure = _closure;
072                    while (variableClosure != null) {
073                        if (variableClosure.inInnerClass()) break;
074                        variableClosure = variableClosure.getParentClosure();
075                    }
076                
077                    if (variableClosure != null) {
078                        il.append(ALOAD_0);
079                        il.append(new GETFIELD(
080                            cpg.addFieldref(variableClosure.getInnerClassName(), 
081                                name, signature)));
082                    }
083                    else {
084                        il.append(_variable.loadInstruction());
085                    }
086                }
087                else {
088                    il.append(_variable.loadInstruction());
089                }
090            }
091            else {
092                final String className = classGen.getClassName();
093                il.append(classGen.loadTranslet());
094                if (classGen.isExternal()) {
095                    il.append(new CHECKCAST(cpg.addClass(className)));
096                }
097                il.append(new GETFIELD(cpg.addFieldref(className,name,signature)));
098            }
099    
100            if (_variable.getType() instanceof NodeSetType) {
101                // The method cloneIterator() also does resetting
102                final int clone = cpg.addInterfaceMethodref(NODE_ITERATOR,
103                                                           "cloneIterator",
104                                                           "()" + 
105                                                            NODE_ITERATOR_SIG);
106                il.append(new INVOKEINTERFACE(clone, 1));
107            }
108        }
109    }