001    /* Copyright (c) 2005-2008, Torbjorn Ekman
002     * All rights reserved.
003     *
004     * Redistribution and use in source and binary forms, with or without
005     * modification, are permitted provided that the following conditions are met:
006     *
007     * 1. Redistributions of source code must retain the above copyright notice,
008     * this list of conditions and the following disclaimer.
009     *
010     * 2. Redistributions in binary form must reproduce the above copyright notice,
011     * this list of conditions and the following disclaimer in the documentation
012     * and/or other materials provided with the distribution.
013     *
014     * 3. Neither the name of the copyright holder nor the names of its
015     * contributors may be used to endorse or promote products derived from this
016     * software without specific prior written permission.
017     *
018     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
022     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028     * POSSIBILITY OF SUCH DAMAGE.
029     */
030    
031    aspect BytecodeCONSTANT {
032      class CONSTANT_Class_Info extends CONSTANT_Info {
033        public int name_index;
034    
035        public CONSTANT_Class_Info(AbstractClassfileParser parser) throws IOException {
036          super(parser);
037          name_index = p.u2();
038        }
039    
040        public String toString() {
041          return "ClassInfo: " + name();
042        }
043    
044        public String name() {
045          String name = ((CONSTANT_Utf8_Info) p.constantPool[name_index]).string();
046          //name = name.replaceAll("\\/", ".");
047          name = name.replace('/', '.');
048          return name;
049        }
050    
051        public String simpleName() {
052          String name = name();
053          //name = name.replace('$', '.');
054          int pos = name.lastIndexOf('.');
055          return name.substring(pos + 1, name.length());
056        }
057    
058        public String packageDecl() {
059          String name = name();
060          //name = name.replace('$', '.');
061          int pos = name.lastIndexOf('.');
062          if (pos == -1) {
063            return "";
064          }
065          return name.substring(0, pos);
066        }
067    
068        public Access access() {
069          String name = name();
070          int pos = name.lastIndexOf('.');
071          String typeName = name.substring(pos + 1, name.length());
072          String packageName = pos == -1 ? "" : name.substring(0, pos);
073          if (typeName.indexOf('$') != -1) {
074            return new BytecodeTypeAccess(packageName, typeName);
075          } else {
076            return new TypeAccess(packageName, typeName);
077          }
078        }
079      }
080    
081      // refineable methods for literal building
082      public static Literal Literal.buildDoubleLiteral(double value) {
083        return new DoubleLiteral(Double.toString(value));
084      }
085    
086      public static Literal Literal.buildFloatLiteral(float value) {
087        return new FloatingPointLiteral(Double.toString(value));
088      }
089    
090      public static Literal Literal.buildIntegerLiteral(int value) {
091        return new IntegerLiteral("0x"+Integer.toHexString(value));
092      }
093    
094      public static Literal Literal.buildLongLiteral(long value) {
095        return new LongLiteral("0x"+Long.toHexString(value));
096      }
097    
098      public static Literal Literal.buildBooleanLiteral(boolean value) {
099        return new BooleanLiteral(value ? "true" : "false");
100      }
101    
102      public static Literal Literal.buildStringLiteral(String value) {
103        return new StringLiteral(value);
104      }
105    
106      class CONSTANT_Double_Info extends CONSTANT_Info {
107        public double value;
108    
109        public CONSTANT_Double_Info(AbstractClassfileParser parser) throws IOException {
110          super(parser);
111          value = p.readDouble();
112        }
113    
114        public String toString() {
115          return "DoubleInfo: " + Double.toString(value);
116        }
117    
118        public Expr expr() {
119          return Literal.buildDoubleLiteral(value);
120        }
121      }
122    
123      class CONSTANT_Fieldref_Info extends CONSTANT_Info {
124        public int class_index;
125        public int name_and_type_index;
126    
127        public CONSTANT_Fieldref_Info(AbstractClassfileParser parser) throws IOException {
128          super(parser);
129          class_index = p.u2();
130          name_and_type_index = p.u2();
131        }
132    
133        public String toString() {
134          return "FieldRefInfo: " + p.constantPool[class_index] + " "
135            + p.constantPool[name_and_type_index];
136        }
137      }
138    
139      class CONSTANT_Float_Info extends CONSTANT_Info {
140        public float value;
141    
142        public CONSTANT_Float_Info(AbstractClassfileParser parser) throws IOException {
143          super(parser);
144          value = p.readFloat();
145        }
146    
147        public String toString() {
148          return "FloatInfo: " + Float.toString(value);
149        }
150    
151        public Expr expr() {
152          return Literal.buildFloatLiteral(value);
153        }
154      }
155    
156      class CONSTANT_Info {
157        protected AbstractClassfileParser p;
158        public CONSTANT_Info(AbstractClassfileParser parser) {
159          p = parser;
160        }
161        public Expr expr() {
162          throw new Error("CONSTANT_info.expr() should not be computed for " + getClass().getName());
163        }
164        public Expr exprAsBoolean() {
165          return expr();
166        }
167      }
168    
169      class CONSTANT_Integer_Info extends CONSTANT_Info {
170        public int value;
171    
172        public CONSTANT_Integer_Info(AbstractClassfileParser parser) throws IOException {
173          super(parser);
174          value = p.readInt();
175        }
176    
177        public String toString() {
178          return "IntegerInfo: " + Integer.toString(value);
179        }
180    
181        public Expr expr() {
182          return Literal.buildIntegerLiteral(value);
183        }
184        public Expr exprAsBoolean() {
185          return Literal.buildBooleanLiteral(value == 0);
186        }
187      }
188      class CONSTANT_InterfaceMethodref_Info extends CONSTANT_Info {
189        public int class_index;
190        public int name_and_type_index;
191    
192        public CONSTANT_InterfaceMethodref_Info(AbstractClassfileParser parser) throws IOException {
193          super(parser);
194          class_index = p.u2();
195          name_and_type_index = p.u2();
196        }
197    
198        public String toString() {
199          return "InterfaceMethodRefInfo: " + p.constantPool[class_index] + " "
200            + p.constantPool[name_and_type_index];
201        }
202      }
203      class CONSTANT_Long_Info extends CONSTANT_Info {
204        public long value;
205    
206        public CONSTANT_Long_Info(AbstractClassfileParser parser) throws IOException {
207          super(parser);
208          value = p.readLong();
209        }
210    
211        public String toString() {
212          return "LongInfo: " + Long.toString(value);
213        }
214    
215        public Expr expr() {
216          return Literal.buildLongLiteral(value);
217        }
218      }
219      class CONSTANT_Methodref_Info extends CONSTANT_Info {
220        public int class_index;
221        public int name_and_type_index;
222    
223        public CONSTANT_Methodref_Info(AbstractClassfileParser parser) throws IOException {
224          super(parser);
225          class_index = p.u2();
226          name_and_type_index = p.u2();
227        }
228    
229        public String toString() {
230          return "MethodRefInfo: " + class_index + " " + name_and_type_index;
231        }
232      }
233    
234      class CONSTANT_NameAndType_Info extends CONSTANT_Info {
235        public int name_index;
236        public int descriptor_index;
237    
238        public CONSTANT_NameAndType_Info(AbstractClassfileParser parser) throws IOException {
239          super(parser);
240          name_index = p.u2();
241          descriptor_index = p.u2();
242        }
243    
244        public String toString() {
245          return "NameAndTypeInfo: " + name_index + " " + descriptor_index;
246        }
247      }
248    
249      class CONSTANT_String_Info extends CONSTANT_Info {
250        public int string_index;
251    
252        public CONSTANT_String_Info(AbstractClassfileParser parser) throws IOException {
253          super(parser);
254          string_index = p.u2();
255        }
256    
257        public Expr expr() {
258          CONSTANT_Utf8_Info i = (CONSTANT_Utf8_Info) p.constantPool[string_index];
259          return Literal.buildStringLiteral(i.string);
260        }
261    
262        public String toString() {
263          return "StringInfo: " + p.constantPool[string_index];
264        }
265      }
266    
267      class CONSTANT_Utf8_Info extends CONSTANT_Info {
268        public String string;
269    
270        public CONSTANT_Utf8_Info(AbstractClassfileParser parser) throws IOException {
271          super(parser);
272          string = p.readUTF();
273        }
274    
275        public String toString() {
276          return "Utf8Info: " + string;
277        }
278    
279        public Expr expr() {
280          return Literal.buildStringLiteral(string);
281        }
282    
283        public String string() {
284          return string;
285        }
286      }
287    
288    }