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 com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
25import com.sun.org.apache.bcel.internal.generic.GETFIELD;
26import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
27import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
28import com.sun.org.apache.bcel.internal.generic.PUSH;
29import com.sun.org.apache.bcel.internal.generic.InstructionList;
30import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
31import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
32import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
33import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
34
35/**
36 * @author Jacek Ambroziak
37 * @author Santiago Pericas-Geertsen
38 * @author Morten Jorgensen
39 */
40final class Comment extends Instruction {
41
42    public void parseContents(Parser parser) {
43        parseChildren(parser);
44    }
45
46    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
47        typeCheckContents(stable);
48        return Type.String;
49    }
50
51    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
52        final ConstantPoolGen cpg = classGen.getConstantPool();
53        final InstructionList il = methodGen.getInstructionList();
54
55        // Shortcut for literal strings
56        Text rawText = null;
57        if (elementCount() == 1) {
58            Object content = elementAt(0);
59            if (content instanceof Text) {
60                rawText = (Text) content;
61            }
62        }
63
64        // If the content is literal text, call comment(char[],int,int) or
65        // comment(String), as appropriate.  Otherwise, use a
66        // StringValueHandler to gather the textual content of the xsl:comment
67        // and call comment(String) with the result.
68        if (rawText != null) {
69            il.append(methodGen.loadHandler());
70
71            if (rawText.canLoadAsArrayOffsetLength()) {
72                rawText.loadAsArrayOffsetLength(classGen, methodGen);
73                final int comment =
74                        cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
75                                                  "comment",
76                                                  "([CII)V");
77                il.append(new INVOKEINTERFACE(comment, 4));
78            } else {
79                il.append(new PUSH(cpg, rawText.getText()));
80                final int comment =
81                        cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
82                                                  "comment",
83                                                  "(" + STRING_SIG + ")V");
84                il.append(new INVOKEINTERFACE(comment, 2));
85            }
86        } else {
87            // Save the current handler base on the stack
88            il.append(methodGen.loadHandler());
89            il.append(DUP);             // first arg to "comment" call
90
91            // Get the translet's StringValueHandler
92            il.append(classGen.loadTranslet());
93            il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
94                                                   "stringValueHandler",
95                                                   STRING_VALUE_HANDLER_SIG)));
96            il.append(DUP);
97            il.append(methodGen.storeHandler());
98
99            // translate contents with substituted handler
100            translateContents(classGen, methodGen);
101
102            // get String out of the handler
103            il.append(new INVOKEVIRTUAL(cpg.addMethodref(STRING_VALUE_HANDLER,
104                                                         "getValue",
105                                                         "()" + STRING_SIG)));
106            // call "comment"
107            final int comment =
108                        cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
109                                                  "comment",
110                                                  "(" + STRING_SIG + ")V");
111            il.append(new INVOKEINTERFACE(comment, 2));
112            // Restore old handler base from stack
113            il.append(methodGen.storeHandler());
114        }
115    }
116}
117