1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2004 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 /* 21 * $Id: CallTemplate.java,v 1.2.4.1 2005/09/12 10:02:41 pvedula Exp $ 22 */ 23 24 package com.sun.org.apache.xalan.internal.xsltc.compiler; 25 26 import com.sun.org.apache.bcel.internal.generic.ALOAD; 27 import com.sun.org.apache.bcel.internal.generic.ASTORE; 28 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 29 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 30 import com.sun.org.apache.bcel.internal.generic.InstructionList; 31 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 37 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 38 import com.sun.org.apache.xml.internal.utils.XML11Char; 39 40 import java.util.Vector; 41 42 /** 43 * @author Jacek Ambroziak 44 * @author Santiago Pericas-Geertsen 45 * @author Erwin Bolwidt <ejb@klomp.org> 46 */ 47 final class CallTemplate extends Instruction { 48 49 /** 50 * Name of template to call. 51 */ 52 private QName _name; 53 54 /** 55 * The array of effective parameters in this CallTemplate. An object in 56 * this array can be either a WithParam or a Param if no WithParam 57 * exists for a particular parameter. 58 */ 59 private Object[] _parameters = null; 60 61 /** 62 * The corresponding template which this CallTemplate calls. 63 */ 64 private Template _calleeTemplate = null; 65 66 public void display(int indent) { 67 indent(indent); 68 System.out.print("CallTemplate"); 69 Util.println(" name " + _name); 70 displayContents(indent + IndentIncrement); 71 } 72 73 public boolean hasWithParams() { 74 return elementCount() > 0; 75 } 76 77 public void parseContents(Parser parser) { 78 final String name = getAttribute("name"); 79 if (name.length() > 0) { 130 } 131 } 132 133 // Generate a valid Java method name 134 final String className = stylesheet.getClassName(); 135 String methodName = Util.escape(_name.toString()); 136 137 // Load standard arguments 138 il.append(classGen.loadTranslet()); 139 il.append(methodGen.loadDOM()); 140 il.append(methodGen.loadIterator()); 141 il.append(methodGen.loadHandler()); 142 il.append(methodGen.loadCurrentNode()); 143 144 // Initialize prefix of method signature 145 StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG 146 + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG); 147 148 // If calling a simply named template, push actual arguments 149 if (_calleeTemplate != null) { 150 Vector calleeParams = _calleeTemplate.getParameters(); 151 int numParams = _parameters.length; 152 153 for (int i = 0; i < numParams; i++) { 154 SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i]; 155 methodSig.append(OBJECT_SIG); // append Object to signature 156 157 // Push 'null' if Param to indicate no actual parameter specified 158 if (node instanceof Param) { 159 il.append(ACONST_NULL); 160 } 161 else { // translate WithParam 162 node.translate(classGen, methodGen); 163 } 164 } 165 } 166 167 // Complete signature and generate invokevirtual call 168 methodSig.append(")V"); 169 il.append(new INVOKEVIRTUAL(cpg.addMethodref(className, 170 methodName, 171 methodSig.toString()))); 172 173 // Do not need to call Translet.popParamFrame() if we are 174 // calling a simple named template. 175 if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) { 176 // Pop parameter frame 177 final int pop = cpg.addMethodref(TRANSLET_CLASS, 178 POP_PARAM_FRAME, 179 POP_PARAM_FRAME_SIG); 180 il.append(classGen.loadTranslet()); 181 il.append(new INVOKEVIRTUAL(pop)); 182 } 183 } 184 185 /** 186 * Return the simple named template which this CallTemplate calls. 187 * Return false if there is no matched template or the matched 188 * template is not a simple named template. 189 */ 190 public Template getCalleeTemplate() { 191 Template foundTemplate 192 = getXSLTC().getParser().getSymbolTable().lookupTemplate(_name); 193 194 return foundTemplate.isSimpleNamedTemplate() ? foundTemplate : null; 195 } 196 197 /** 198 * Build the list of effective parameters in this CallTemplate. 199 * The parameters of the called template are put into the array first. 200 * Then we visit the WithParam children of this CallTemplate and replace 201 * the Param with a corresponding WithParam having the same name. 202 */ 203 private void buildParameterList() { 204 // Put the parameters from the called template into the array first. 205 // This is to ensure the order of the parameters. 206 Vector defaultParams = _calleeTemplate.getParameters(); 207 int numParams = defaultParams.size(); 208 _parameters = new Object[numParams]; 209 for (int i = 0; i < numParams; i++) { 210 _parameters[i] = defaultParams.elementAt(i); 211 } 212 213 // Replace a Param with a WithParam if they have the same name. 214 int count = elementCount(); 215 for (int i = 0; i < count; i++) { 216 Object node = elementAt(i); 217 218 // Ignore if not WithParam 219 if (node instanceof WithParam) { 220 WithParam withParam = (WithParam)node; 221 QName name = withParam.getName(); 222 223 // Search for a Param with the same name 224 for (int k = 0; k < numParams; k++) { 225 Object object = _parameters[k]; 226 if (object instanceof Param 227 && ((Param)object).getName().equals(name)) { 228 withParam.setDoParameterOptimization(true); 229 _parameters[k] = withParam; 230 break; 231 } 232 else if (object instanceof WithParam 233 && ((WithParam)object).getName().equals(name)) { 234 withParam.setDoParameterOptimization(true); 235 _parameters[k] = withParam; 236 break; 237 } 238 } 239 } 240 } 241 } 242 } | 1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Copyright 2001-2004 The Apache Software Foundation. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 23 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 24 import com.sun.org.apache.bcel.internal.generic.InstructionList; 25 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 26 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 31 import com.sun.org.apache.xml.internal.utils.XML11Char; 32 33 import java.util.Vector; 34 35 /** 36 * @author Jacek Ambroziak 37 * @author Santiago Pericas-Geertsen 38 * @author Erwin Bolwidt <ejb@klomp.org> 39 */ 40 final class CallTemplate extends Instruction { 41 42 /** 43 * Name of template to call. 44 */ 45 private QName _name; 46 47 /** 48 * The array of effective parameters in this CallTemplate. An object in 49 * this array can be either a WithParam or a Param if no WithParam 50 * exists for a particular parameter. 51 */ 52 private SyntaxTreeNode[] _parameters = null; 53 54 /** 55 * The corresponding template which this CallTemplate calls. 56 */ 57 private Template _calleeTemplate = null; 58 59 public void display(int indent) { 60 indent(indent); 61 System.out.print("CallTemplate"); 62 Util.println(" name " + _name); 63 displayContents(indent + IndentIncrement); 64 } 65 66 public boolean hasWithParams() { 67 return elementCount() > 0; 68 } 69 70 public void parseContents(Parser parser) { 71 final String name = getAttribute("name"); 72 if (name.length() > 0) { 123 } 124 } 125 126 // Generate a valid Java method name 127 final String className = stylesheet.getClassName(); 128 String methodName = Util.escape(_name.toString()); 129 130 // Load standard arguments 131 il.append(classGen.loadTranslet()); 132 il.append(methodGen.loadDOM()); 133 il.append(methodGen.loadIterator()); 134 il.append(methodGen.loadHandler()); 135 il.append(methodGen.loadCurrentNode()); 136 137 // Initialize prefix of method signature 138 StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG 139 + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG); 140 141 // If calling a simply named template, push actual arguments 142 if (_calleeTemplate != null) { 143 int numParams = _parameters.length; 144 145 for (int i = 0; i < numParams; i++) { 146 SyntaxTreeNode node = _parameters[i]; 147 methodSig.append(OBJECT_SIG); // append Object to signature 148 149 // Push 'null' if Param to indicate no actual parameter specified 150 if (node instanceof Param) { 151 il.append(ACONST_NULL); 152 } 153 else { // translate WithParam 154 node.translate(classGen, methodGen); 155 } 156 } 157 } 158 159 // Complete signature and generate invokevirtual call 160 methodSig.append(")V"); 161 il.append(new INVOKEVIRTUAL(cpg.addMethodref(className, 162 methodName, 163 methodSig.toString()))); 164 165 // release temporary result trees 166 if (_parameters != null) { 167 for (int i = 0; i < _parameters.length; i++) { 168 if (_parameters[i] instanceof WithParam) { 169 ((WithParam)_parameters[i]).releaseResultTree(classGen, methodGen); 170 } 171 } 172 } 173 174 // Do not need to call Translet.popParamFrame() if we are 175 // calling a simple named template. 176 if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) { 177 // Pop parameter frame 178 final int pop = cpg.addMethodref(TRANSLET_CLASS, 179 POP_PARAM_FRAME, 180 POP_PARAM_FRAME_SIG); 181 il.append(classGen.loadTranslet()); 182 il.append(new INVOKEVIRTUAL(pop)); 183 } 184 } 185 186 /** 187 * Return the simple named template which this CallTemplate calls. 188 * Return false if there is no matched template or the matched 189 * template is not a simple named template. 190 */ 191 public Template getCalleeTemplate() { 192 Template foundTemplate 193 = getXSLTC().getParser().getSymbolTable().lookupTemplate(_name); 194 195 return foundTemplate.isSimpleNamedTemplate() ? foundTemplate : null; 196 } 197 198 /** 199 * Build the list of effective parameters in this CallTemplate. 200 * The parameters of the called template are put into the array first. 201 * Then we visit the WithParam children of this CallTemplate and replace 202 * the Param with a corresponding WithParam having the same name. 203 */ 204 private void buildParameterList() { 205 // Put the parameters from the called template into the array first. 206 // This is to ensure the order of the parameters. 207 Vector<Param> defaultParams = _calleeTemplate.getParameters(); 208 int numParams = defaultParams.size(); 209 _parameters = new SyntaxTreeNode[numParams]; 210 for (int i = 0; i < numParams; i++) { 211 _parameters[i] = defaultParams.elementAt(i); 212 } 213 214 // Replace a Param with a WithParam if they have the same name. 215 int count = elementCount(); 216 for (int i = 0; i < count; i++) { 217 Object node = elementAt(i); 218 219 // Ignore if not WithParam 220 if (node instanceof WithParam) { 221 WithParam withParam = (WithParam)node; 222 QName name = withParam.getName(); 223 224 // Search for a Param with the same name 225 for (int k = 0; k < numParams; k++) { 226 SyntaxTreeNode parm = _parameters[k]; 227 if (parm instanceof Param 228 && ((Param)parm).getName().equals(name)) { 229 withParam.setDoParameterOptimization(true); 230 _parameters[k] = withParam; 231 break; 232 } 233 else if (parm instanceof WithParam 234 && ((WithParam)parm).getName().equals(name)) { 235 withParam.setDoParameterOptimization(true); 236 _parameters[k] = withParam; 237 break; 238 } 239 } 240 } 241 } 242 } 243 } |