1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xalan.internal.xsltc.compiler; 23 24import java.util.Vector; 25 26import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 27import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 28import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 29import com.sun.org.apache.bcel.internal.generic.Instruction; 30import com.sun.org.apache.bcel.internal.generic.InstructionList; 31import com.sun.org.apache.bcel.internal.generic.NEW; 32import com.sun.org.apache.bcel.internal.generic.PUSH; 33import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 34import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 35import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 36import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 37 38/** 39 * @author Jacek Ambroziak 40 * @author Santiago Pericas-Geertsen 41 */ 42final class ConcatCall extends FunctionCall { 43 public ConcatCall(QName fname, Vector arguments) { 44 super(fname, arguments); 45 } 46 47 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 48 for (int i = 0; i < argumentCount(); i++) { 49 final Expression exp = argument(i); 50 if (!exp.typeCheck(stable).identicalTo(Type.String)) { 51 setArgument(i, new CastExpr(exp, Type.String)); 52 } 53 } 54 return _type = Type.String; 55 } 56 57 /** translate leaves a String on the stack */ 58 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 59 final ConstantPoolGen cpg = classGen.getConstantPool(); 60 final InstructionList il = methodGen.getInstructionList(); 61 final int nArgs = argumentCount(); 62 63 switch (nArgs) { 64 case 0: 65 il.append(new PUSH(cpg, EMPTYSTRING)); 66 break; 67 68 case 1: 69 argument().translate(classGen, methodGen); 70 break; 71 72 default: 73 final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS, 74 "<init>", "()V"); 75 final Instruction append = 76 new INVOKEVIRTUAL(cpg.addMethodref(STRING_BUFFER_CLASS, 77 "append", 78 "("+STRING_SIG+")" 79 +STRING_BUFFER_SIG)); 80 81 final int toString = cpg.addMethodref(STRING_BUFFER_CLASS, 82 "toString", 83 "()"+STRING_SIG); 84 85 il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS))); 86 il.append(DUP); 87 il.append(new INVOKESPECIAL(initBuffer)); 88 for (int i = 0; i < nArgs; i++) { 89 argument(i).translate(classGen, methodGen); 90 il.append(append); 91 } 92 il.append(new INVOKEVIRTUAL(toString)); 93 } 94 } 95} 96