286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 2001-2005 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A/*
286N/A * $Id: AbsoluteLocationPath.java,v 1.2.4.1 2005/09/12 09:44:03 pvedula Exp $
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xalan.internal.xsltc.compiler;
286N/A
286N/Aimport com.sun.org.apache.bcel.internal.generic.ALOAD;
286N/Aimport com.sun.org.apache.bcel.internal.generic.ASTORE;
286N/Aimport com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
286N/Aimport com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
286N/Aimport com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
286N/Aimport com.sun.org.apache.bcel.internal.generic.InstructionList;
286N/Aimport com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
286N/Aimport com.sun.org.apache.bcel.internal.generic.NEW;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeType;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
286N/A
286N/A/**
286N/A * @author Jacek Ambroziak
286N/A * @author Santiago Pericas-Geertsen
286N/A */
286N/Afinal class AbsoluteLocationPath extends Expression {
286N/A private Expression _path; // may be null
286N/A
286N/A public AbsoluteLocationPath() {
286N/A _path = null;
286N/A }
286N/A
286N/A public AbsoluteLocationPath(Expression path) {
286N/A _path = path;
286N/A if (path != null) {
286N/A _path.setParent(this);
286N/A }
286N/A }
286N/A
286N/A public void setParser(Parser parser) {
286N/A super.setParser(parser);
286N/A if (_path != null) {
286N/A _path.setParser(parser);
286N/A }
286N/A }
286N/A
286N/A public Expression getPath() {
286N/A return(_path);
286N/A }
286N/A
286N/A public String toString() {
286N/A return "AbsoluteLocationPath(" +
286N/A (_path != null ? _path.toString() : "null") + ')';
286N/A }
286N/A
286N/A public Type typeCheck(SymbolTable stable) throws TypeCheckError {
286N/A if (_path != null) {
286N/A final Type ptype = _path.typeCheck(stable);
286N/A if (ptype instanceof NodeType) { // promote to node-set
286N/A _path = new CastExpr(_path, Type.NodeSet);
286N/A }
286N/A }
286N/A return _type = Type.NodeSet;
286N/A }
286N/A
286N/A public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
286N/A final ConstantPoolGen cpg = classGen.getConstantPool();
286N/A final InstructionList il = methodGen.getInstructionList();
286N/A if (_path != null) {
286N/A final int initAI = cpg.addMethodref(ABSOLUTE_ITERATOR,
286N/A "<init>",
286N/A "("
286N/A + NODE_ITERATOR_SIG
286N/A + ")V");
286N/A
286N/A // Compile relative path iterator(s)
286N/A //
286N/A // Backwards branches are prohibited if an uninitialized object is
286N/A // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
286N/A // We don't know whether this code might contain backwards branches,
286N/A // so we mustn't create the new object until after we've created
286N/A // this argument to its constructor. Instead we calculate the
286N/A // value of the argument to the constructor first, store it in
286N/A // a temporary variable, create the object and reload the argument
286N/A // from the temporary to avoid the problem.
286N/A _path.translate(classGen, methodGen);
286N/A LocalVariableGen relPathIterator
286N/A = methodGen.addLocalVariable("abs_location_path_tmp",
286N/A Util.getJCRefType(NODE_ITERATOR_SIG),
286N/A null, null);
286N/A relPathIterator.setStart(
286N/A il.append(new ASTORE(relPathIterator.getIndex())));
286N/A
286N/A // Create new AbsoluteIterator
286N/A il.append(new NEW(cpg.addClass(ABSOLUTE_ITERATOR)));
286N/A il.append(DUP);
286N/A relPathIterator.setEnd(
286N/A il.append(new ALOAD(relPathIterator.getIndex())));
286N/A
286N/A // Initialize AbsoluteIterator with iterator from the stack
286N/A il.append(new INVOKESPECIAL(initAI));
286N/A }
286N/A else {
286N/A final int gitr = cpg.addInterfaceMethodref(DOM_INTF,
286N/A "getIterator",
286N/A "()"+NODE_ITERATOR_SIG);
286N/A il.append(methodGen.loadDOM());
286N/A il.append(new INVOKEINTERFACE(gitr, 1));
286N/A }
286N/A }
286N/A}