|
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 |
|
22 package com.sun.org.apache.xalan.internal.xsltc.compiler.util; |
|
23 |
|
24 import com.sun.org.apache.bcel.internal.generic.ALOAD; |
|
25 import com.sun.org.apache.bcel.internal.generic.ASTORE; |
|
26 import com.sun.org.apache.bcel.internal.generic.BranchHandle; |
|
27 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; |
|
28 import com.sun.org.apache.bcel.internal.generic.GOTO; |
|
29 import com.sun.org.apache.bcel.internal.generic.IFEQ; |
|
30 import com.sun.org.apache.bcel.internal.generic.IFNONNULL; |
|
31 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; |
|
32 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; |
|
33 import com.sun.org.apache.bcel.internal.generic.Instruction; |
|
34 import com.sun.org.apache.bcel.internal.generic.InstructionList; |
|
35 import com.sun.org.apache.bcel.internal.generic.PUSH; |
|
36 import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; |
|
37 import com.sun.org.apache.xalan.internal.xsltc.compiler.FlowList; |
|
38 |
|
39 /** |
|
40 * @author Jacek Ambroziak |
|
41 * @author Santiago Pericas-Geertsen |
|
42 */ |
|
43 public class StringType extends Type { |
|
44 protected StringType() {} |
|
45 |
|
46 public String toString() { |
|
47 return "string"; |
|
48 } |
|
49 |
|
50 public boolean identicalTo(Type other) { |
|
51 return this == other; |
|
52 } |
|
53 |
|
54 public String toSignature() { |
|
55 return "Ljava/lang/String;"; |
|
56 } |
|
57 |
|
58 public boolean isSimple() { |
|
59 return true; |
|
60 } |
|
61 |
|
62 public com.sun.org.apache.bcel.internal.generic.Type toJCType() { |
|
63 return com.sun.org.apache.bcel.internal.generic.Type.STRING; |
|
64 } |
|
65 |
|
66 /** |
|
67 * Translates a string into an object of internal type <code>type</code>. |
|
68 * The translation to int is undefined since strings are always converted |
|
69 * to reals in arithmetic expressions. |
|
70 * |
|
71 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo |
|
72 */ |
|
73 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, |
|
74 Type type) { |
|
75 if (type == Type.Boolean) { |
|
76 translateTo(classGen, methodGen, (BooleanType) type); |
|
77 } |
|
78 else if (type == Type.Real) { |
|
79 translateTo(classGen, methodGen, (RealType) type); |
|
80 } |
|
81 else if (type == Type.Reference) { |
|
82 translateTo(classGen, methodGen, (ReferenceType) type); |
|
83 } |
|
84 else if (type == Type.ObjectString) { |
|
85 // NOP -> same representation |
|
86 } |
|
87 else { |
|
88 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, |
|
89 toString(), type.toString()); |
|
90 classGen.getParser().reportError(Constants.FATAL, err); |
|
91 } |
|
92 } |
|
93 |
|
94 /** |
|
95 * Translates a string into a synthesized boolean. |
|
96 * |
|
97 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo |
|
98 */ |
|
99 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, |
|
100 BooleanType type) { |
|
101 final InstructionList il = methodGen.getInstructionList(); |
|
102 FlowList falsel = translateToDesynthesized(classGen, methodGen, type); |
|
103 il.append(ICONST_1); |
|
104 final BranchHandle truec = il.append(new GOTO(null)); |
|
105 falsel.backPatch(il.append(ICONST_0)); |
|
106 truec.setTarget(il.append(NOP)); |
|
107 } |
|
108 |
|
109 /** |
|
110 * Translates a string into a real by calling stringToReal() from the |
|
111 * basis library. |
|
112 * |
|
113 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo |
|
114 */ |
|
115 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, |
|
116 RealType type) { |
|
117 final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
118 final InstructionList il = methodGen.getInstructionList(); |
|
119 il.append(new INVOKESTATIC(cpg.addMethodref(BASIS_LIBRARY_CLASS, |
|
120 STRING_TO_REAL, |
|
121 STRING_TO_REAL_SIG))); |
|
122 } |
|
123 |
|
124 /** |
|
125 * Translates a string into a non-synthesized boolean. It does not push a |
|
126 * 0 or a 1 but instead returns branchhandle list to be appended to the |
|
127 * false list. |
|
128 * |
|
129 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized |
|
130 */ |
|
131 public FlowList translateToDesynthesized(ClassGenerator classGen, |
|
132 MethodGenerator methodGen, |
|
133 BooleanType type) { |
|
134 final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
135 final InstructionList il = methodGen.getInstructionList(); |
|
136 |
|
137 il.append(new INVOKEVIRTUAL(cpg.addMethodref(STRING_CLASS, |
|
138 "length", "()I"))); |
|
139 return new FlowList(il.append(new IFEQ(null))); |
|
140 } |
|
141 |
|
142 /** |
|
143 * Expects a string on the stack and pushes a boxed string. |
|
144 * Strings are already boxed so the translation is just a NOP. |
|
145 * |
|
146 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo |
|
147 */ |
|
148 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, |
|
149 ReferenceType type) { |
|
150 methodGen.getInstructionList().append(NOP); |
|
151 } |
|
152 |
|
153 /** |
|
154 * Translates a internal string into an external (Java) string. |
|
155 * |
|
156 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateFrom |
|
157 */ |
|
158 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, |
|
159 Class clazz) |
|
160 { |
|
161 // Is String <: clazz? I.e. clazz in { String, Object } |
|
162 if (clazz.isAssignableFrom(java.lang.String.class)) { |
|
163 methodGen.getInstructionList().append(NOP); |
|
164 } |
|
165 else { |
|
166 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, |
|
167 toString(), clazz.getName()); |
|
168 classGen.getParser().reportError(Constants.FATAL, err); |
|
169 } |
|
170 } |
|
171 |
|
172 /** |
|
173 * Translates an external (primitive) Java type into a string. |
|
174 * |
|
175 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateFrom |
|
176 */ |
|
177 public void translateFrom(ClassGenerator classGen, |
|
178 MethodGenerator methodGen, Class clazz) |
|
179 { |
|
180 final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
181 final InstructionList il = methodGen.getInstructionList(); |
|
182 |
|
183 if (clazz.getName().equals("java.lang.String")) { |
|
184 // same internal representation, convert null to "" |
|
185 il.append(DUP); |
|
186 final BranchHandle ifNonNull = il.append(new IFNONNULL(null)); |
|
187 il.append(POP); |
|
188 il.append(new PUSH(cpg, "")); |
|
189 ifNonNull.setTarget(il.append(NOP)); |
|
190 } |
|
191 else { |
|
192 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, |
|
193 toString(), clazz.getName()); |
|
194 classGen.getParser().reportError(Constants.FATAL, err); |
|
195 } |
|
196 } |
|
197 |
|
198 /** |
|
199 * Translates an object of this type to its boxed representation. |
|
200 */ |
|
201 public void translateBox(ClassGenerator classGen, |
|
202 MethodGenerator methodGen) { |
|
203 translateTo(classGen, methodGen, Type.Reference); |
|
204 } |
|
205 |
|
206 /** |
|
207 * Translates an object of this type to its unboxed representation. |
|
208 */ |
|
209 public void translateUnBox(ClassGenerator classGen, |
|
210 MethodGenerator methodGen) { |
|
211 methodGen.getInstructionList().append(NOP); |
|
212 } |
|
213 |
|
214 /** |
|
215 * Returns the class name of an internal type's external representation. |
|
216 */ |
|
217 public String getClassName() { |
|
218 return(STRING_CLASS); |
|
219 } |
|
220 |
|
221 |
|
222 public Instruction LOAD(int slot) { |
|
223 return new ALOAD(slot); |
|
224 } |
|
225 |
|
226 public Instruction STORE(int slot) { |
|
227 return new ASTORE(slot); |
|
228 } |
|
229 } |