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: VariableRef.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
033 /**
034 * @author Jacek Ambroziak
035 * @author Santiago Pericas-Geertsen
036 * @author Morten Jorgensen
037 * @author Erwin Bolwidt <ejb@klomp.org>
038 */
039 final class VariableRef extends VariableRefBase {
040
041 public VariableRef(Variable variable) {
042 super(variable);
043 }
044
045 public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
046 final ConstantPoolGen cpg = classGen.getConstantPool();
047 final InstructionList il = methodGen.getInstructionList();
048
049 // Fall-through for variables that are implemented as methods
050 if (_type.implementedAsMethod()) return;
051
052 final String name = _variable.getEscapedName();
053 final String signature = _type.toSignature();
054
055 if (_variable.isLocal()) {
056 if (classGen.isExternal()) {
057 Closure variableClosure = _closure;
058 while (variableClosure != null) {
059 if (variableClosure.inInnerClass()) break;
060 variableClosure = variableClosure.getParentClosure();
061 }
062
063 if (variableClosure != null) {
064 il.append(ALOAD_0);
065 il.append(new GETFIELD(
066 cpg.addFieldref(variableClosure.getInnerClassName(),
067 name, signature)));
068 }
069 else {
070 il.append(_variable.loadInstruction());
071 }
072 }
073 else {
074 il.append(_variable.loadInstruction());
075 }
076 }
077 else {
078 final String className = classGen.getClassName();
079 il.append(classGen.loadTranslet());
080 if (classGen.isExternal()) {
081 il.append(new CHECKCAST(cpg.addClass(className)));
082 }
083 il.append(new GETFIELD(cpg.addFieldref(className,name,signature)));
084 }
085
086 if (_variable.getType() instanceof NodeSetType) {
087 // The method cloneIterator() also does resetting
088 final int clone = cpg.addInterfaceMethodref(NODE_ITERATOR,
089 "cloneIterator",
090 "()" +
091 NODE_ITERATOR_SIG);
092 il.append(new INVOKEINTERFACE(clone, 1));
093 }
094 }
095 }