001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.classfile.io;
022:
023: import proguard.classfile.*;
024: import proguard.classfile.attribute.*;
025: import proguard.classfile.attribute.annotation.*;
026: import proguard.classfile.attribute.annotation.visitor.*;
027: import proguard.classfile.attribute.preverification.*;
028: import proguard.classfile.attribute.preverification.visitor.*;
029: import proguard.classfile.attribute.visitor.*;
030: import proguard.classfile.constant.*;
031: import proguard.classfile.constant.visitor.ConstantVisitor;
032: import proguard.classfile.util.*;
033: import proguard.classfile.visitor.*;
034:
035: import java.io.*;
036:
037: /**
038: * This ClassVisitor writes out the ProgramClass objects that it visits to the
039: * given DataOutput object.
040: *
041: * @author Eric Lafortune
042: */
043: public class ProgramClassWriter extends SimplifiedVisitor implements
044: ClassVisitor, MemberVisitor, ConstantVisitor, AttributeVisitor {
045: private RuntimeDataOutput dataOutput;
046:
047: private final ConstantBodyWriter constantBodyWriter = new ConstantBodyWriter();
048: private final AttributeBodyWriter attributeBodyWriter = new AttributeBodyWriter();
049: private final StackMapFrameBodyWriter stackMapFrameBodyWriter = new StackMapFrameBodyWriter();
050: private final VerificationTypeBodyWriter verificationTypeBodyWriter = new VerificationTypeBodyWriter();
051: private final ElementValueBodyWriter elementValueBodyWriter = new ElementValueBodyWriter();
052:
053: /**
054: * Creates a new ProgramClassWriter for reading from the given DataOutput.
055: */
056: public ProgramClassWriter(DataOutput dataOutput) {
057: this .dataOutput = new RuntimeDataOutput(dataOutput);
058: }
059:
060: // Implementations for ClassVisitor.
061:
062: public void visitProgramClass(ProgramClass programClass) {
063: // Write the magic number.
064: dataOutput.writeInt(programClass.u4magic);
065:
066: // Write the version numbers.
067: dataOutput.writeShort(ClassUtil
068: .internalMinorClassVersion(programClass.u4version));
069: dataOutput.writeShort(ClassUtil
070: .internalMajorClassVersion(programClass.u4version));
071:
072: // Write the constant pool.
073: dataOutput.writeShort(programClass.u2constantPoolCount);
074:
075: programClass.constantPoolEntriesAccept(this );
076:
077: // Write the general class information.
078: dataOutput.writeShort(programClass.u2accessFlags);
079: dataOutput.writeShort(programClass.u2this Class);
080: dataOutput.writeShort(programClass.u2super Class);
081:
082: // Write the interfaces.
083: dataOutput.writeShort(programClass.u2interfacesCount);
084:
085: for (int index = 0; index < programClass.u2interfacesCount; index++) {
086: dataOutput.writeShort(programClass.u2interfaces[index]);
087: }
088:
089: // Write the fields.
090: dataOutput.writeShort(programClass.u2fieldsCount);
091:
092: programClass.fieldsAccept(this );
093:
094: // Write the methods.
095: dataOutput.writeShort(programClass.u2methodsCount);
096:
097: programClass.methodsAccept(this );
098:
099: // Write the class attributes.
100: dataOutput.writeShort(programClass.u2attributesCount);
101:
102: programClass.attributesAccept(this );
103: }
104:
105: public void visitLibraryClass(LibraryClass libraryClass) {
106: }
107:
108: // Implementations for MemberVisitor.
109:
110: public void visitProgramField(ProgramClass programClass,
111: ProgramField programField) {
112: // Write the general field information.
113: dataOutput.writeShort(programField.u2accessFlags);
114: dataOutput.writeShort(programField.u2nameIndex);
115: dataOutput.writeShort(programField.u2descriptorIndex);
116:
117: // Write the field attributes.
118: dataOutput.writeShort(programField.u2attributesCount);
119:
120: programField.attributesAccept(programClass, this );
121: }
122:
123: public void visitProgramMethod(ProgramClass programClass,
124: ProgramMethod programMethod) {
125: // Write the general method information.
126: dataOutput.writeShort(programMethod.u2accessFlags);
127: dataOutput.writeShort(programMethod.u2nameIndex);
128: dataOutput.writeShort(programMethod.u2descriptorIndex);
129:
130: // Write the method attributes.
131: dataOutput.writeShort(programMethod.u2attributesCount);
132:
133: programMethod.attributesAccept(programClass, this );
134: }
135:
136: public void visitLibraryMember(LibraryClass libraryClass,
137: LibraryMember libraryMember) {
138: }
139:
140: // Implementations for ConstantVisitor.
141:
142: public void visitAnyConstant(Clazz clazz, Constant constant) {
143: // Write the tag.
144: dataOutput.writeByte(constant.getTag());
145:
146: // Write the actual body.
147: constant.accept(clazz, constantBodyWriter);
148: }
149:
150: private class ConstantBodyWriter extends SimplifiedVisitor
151: implements ConstantVisitor {
152: // Implementations for ConstantVisitor.
153:
154: public void visitIntegerConstant(Clazz clazz,
155: IntegerConstant integerConstant) {
156: dataOutput.writeInt(integerConstant.u4value);
157: }
158:
159: public void visitLongConstant(Clazz clazz,
160: LongConstant longConstant) {
161: dataOutput.writeLong(longConstant.u8value);
162: }
163:
164: public void visitFloatConstant(Clazz clazz,
165: FloatConstant floatConstant) {
166: dataOutput.writeFloat(floatConstant.f4value);
167: }
168:
169: public void visitDoubleConstant(Clazz clazz,
170: DoubleConstant doubleConstant) {
171: dataOutput.writeDouble(doubleConstant.f8value);
172: }
173:
174: public void visitStringConstant(Clazz clazz,
175: StringConstant stringConstant) {
176: dataOutput.writeShort(stringConstant.u2stringIndex);
177: }
178:
179: public void visitUtf8Constant(Clazz clazz,
180: Utf8Constant utf8Constant) {
181: byte[] bytes = utf8Constant.getBytes();
182:
183: dataOutput.writeShort(bytes.length);
184: dataOutput.write(bytes);
185: }
186:
187: public void visitAnyRefConstant(Clazz clazz,
188: RefConstant refConstant) {
189: dataOutput.writeShort(refConstant.u2classIndex);
190: dataOutput.writeShort(refConstant.u2nameAndTypeIndex);
191: }
192:
193: public void visitClassConstant(Clazz clazz,
194: ClassConstant classConstant) {
195: dataOutput.writeShort(classConstant.u2nameIndex);
196: }
197:
198: public void visitNameAndTypeConstant(Clazz clazz,
199: NameAndTypeConstant nameAndTypeConstant) {
200: dataOutput.writeShort(nameAndTypeConstant.u2nameIndex);
201: dataOutput
202: .writeShort(nameAndTypeConstant.u2descriptorIndex);
203: }
204: }
205:
206: // Implementations for AttributeVisitor.
207:
208: public void visitAnyAttribute(Clazz clazz, Attribute attribute) {
209: // Write the attribute name index.
210: dataOutput.writeShort(attribute.u2attributeNameIndex);
211:
212: // We'll write the attribute body into an array first, so we can
213: // automatically figure out its length.
214: ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
215:
216: // Temporarily replace the current data output.
217: RuntimeDataOutput oldDataOutput = dataOutput;
218: dataOutput = new RuntimeDataOutput(new DataOutputStream(
219: byteArrayOutputStream));
220:
221: // Write the attribute body into the array. Note that the
222: // accept method with two dummy null arguments never throws
223: // an UnsupportedOperationException.
224: attribute.accept(clazz, null, null, attributeBodyWriter);
225:
226: // Restore the original data output.
227: dataOutput = oldDataOutput;
228:
229: // Write the attribute length and body.
230: byte[] info = byteArrayOutputStream.toByteArray();
231:
232: dataOutput.writeInt(info.length);
233: dataOutput.write(info);
234: }
235:
236: private class AttributeBodyWriter extends SimplifiedVisitor
237: implements AttributeVisitor, InnerClassesInfoVisitor,
238: ExceptionInfoVisitor, StackMapFrameVisitor,
239: VerificationTypeVisitor, LineNumberInfoVisitor,
240: LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor,
241: AnnotationVisitor, ElementValueVisitor {
242: // Implementations for AttributeVisitor.
243:
244: public void visitUnknownAttribute(Clazz clazz,
245: UnknownAttribute unknownAttribute) {
246: // Write the unknown information.
247: byte[] info = new byte[unknownAttribute.u4attributeLength];
248: dataOutput.write(info);
249: unknownAttribute.info = info;
250: }
251:
252: public void visitSourceFileAttribute(Clazz clazz,
253: SourceFileAttribute sourceFileAttribute) {
254: dataOutput
255: .writeShort(sourceFileAttribute.u2sourceFileIndex);
256: }
257:
258: public void visitSourceDirAttribute(Clazz clazz,
259: SourceDirAttribute sourceDirAttribute) {
260: dataOutput.writeShort(sourceDirAttribute.u2sourceDirIndex);
261: }
262:
263: public void visitInnerClassesAttribute(Clazz clazz,
264: InnerClassesAttribute innerClassesAttribute) {
265: // Write the inner classes.
266: dataOutput.writeShort(innerClassesAttribute.u2classesCount);
267:
268: innerClassesAttribute.innerClassEntriesAccept(clazz, this );
269: }
270:
271: public void visitEnclosingMethodAttribute(Clazz clazz,
272: EnclosingMethodAttribute enclosingMethodAttribute) {
273: dataOutput
274: .writeShort(enclosingMethodAttribute.u2classIndex);
275: dataOutput
276: .writeShort(enclosingMethodAttribute.u2nameAndTypeIndex);
277: }
278:
279: public void visitDeprecatedAttribute(Clazz clazz,
280: DeprecatedAttribute deprecatedAttribute) {
281: // This attribute does not contain any additional information.
282: }
283:
284: public void visitSyntheticAttribute(Clazz clazz,
285: SyntheticAttribute syntheticAttribute) {
286: // This attribute does not contain any additional information.
287: }
288:
289: public void visitSignatureAttribute(Clazz clazz,
290: SignatureAttribute signatureAttribute) {
291: dataOutput.writeShort(signatureAttribute.u2signatureIndex);
292: }
293:
294: public void visitConstantValueAttribute(Clazz clazz,
295: Field field,
296: ConstantValueAttribute constantValueAttribute) {
297: dataOutput
298: .writeShort(constantValueAttribute.u2constantValueIndex);
299: }
300:
301: public void visitExceptionsAttribute(Clazz clazz,
302: Method method, ExceptionsAttribute exceptionsAttribute) {
303: // Write the exceptions.
304: dataOutput
305: .writeShort(exceptionsAttribute.u2exceptionIndexTableLength);
306:
307: for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++) {
308: dataOutput
309: .writeShort(exceptionsAttribute.u2exceptionIndexTable[index]);
310: }
311: }
312:
313: public void visitCodeAttribute(Clazz clazz, Method method,
314: CodeAttribute codeAttribute) {
315: // Write the stack size and local variable frame size.
316: dataOutput.writeShort(codeAttribute.u2maxStack);
317: dataOutput.writeShort(codeAttribute.u2maxLocals);
318:
319: // Write the byte code.
320: dataOutput.writeInt(codeAttribute.u4codeLength);
321:
322: dataOutput.write(codeAttribute.code, 0,
323: codeAttribute.u4codeLength);
324:
325: // Write the exceptions.
326: dataOutput.writeShort(codeAttribute.u2exceptionTableLength);
327:
328: codeAttribute.exceptionsAccept(clazz, method, this );
329:
330: // Write the code attributes.
331: dataOutput.writeShort(codeAttribute.u2attributesCount);
332:
333: codeAttribute.attributesAccept(clazz, method,
334: ProgramClassWriter.this );
335: }
336:
337: public void visitStackMapAttribute(Clazz clazz, Method method,
338: CodeAttribute codeAttribute,
339: StackMapAttribute stackMapAttribute) {
340: // Write the stack map frames (only full frames, without tag).
341: dataOutput
342: .writeShort(stackMapAttribute.u2stackMapFramesCount);
343:
344: stackMapAttribute.stackMapFramesAccept(clazz, method,
345: codeAttribute, stackMapFrameBodyWriter);
346: }
347:
348: public void visitStackMapTableAttribute(Clazz clazz,
349: Method method, CodeAttribute codeAttribute,
350: StackMapTableAttribute stackMapTableAttribute) {
351: // Write the stack map frames.
352: dataOutput
353: .writeShort(stackMapTableAttribute.u2stackMapFramesCount);
354:
355: stackMapTableAttribute.stackMapFramesAccept(clazz, method,
356: codeAttribute, this );
357: }
358:
359: public void visitLineNumberTableAttribute(Clazz clazz,
360: Method method, CodeAttribute codeAttribute,
361: LineNumberTableAttribute lineNumberTableAttribute) {
362: // Write the line numbers.
363: dataOutput
364: .writeShort(lineNumberTableAttribute.u2lineNumberTableLength);
365:
366: lineNumberTableAttribute.lineNumbersAccept(clazz, method,
367: codeAttribute, this );
368: }
369:
370: public void visitLocalVariableTableAttribute(Clazz clazz,
371: Method method, CodeAttribute codeAttribute,
372: LocalVariableTableAttribute localVariableTableAttribute) {
373: // Write the local variables.
374: dataOutput
375: .writeShort(localVariableTableAttribute.u2localVariableTableLength);
376:
377: localVariableTableAttribute.localVariablesAccept(clazz,
378: method, codeAttribute, this );
379: }
380:
381: public void visitLocalVariableTypeTableAttribute(
382: Clazz clazz,
383: Method method,
384: CodeAttribute codeAttribute,
385: LocalVariableTypeTableAttribute localVariableTypeTableAttribute) {
386: // Write the local variable types.
387: dataOutput
388: .writeShort(localVariableTypeTableAttribute.u2localVariableTypeTableLength);
389:
390: localVariableTypeTableAttribute.localVariablesAccept(clazz,
391: method, codeAttribute, this );
392: }
393:
394: public void visitAnyAnnotationsAttribute(Clazz clazz,
395: AnnotationsAttribute annotationsAttribute) {
396: // Write the annotations.
397: dataOutput
398: .writeShort(annotationsAttribute.u2annotationsCount);
399:
400: annotationsAttribute.annotationsAccept(clazz, this );
401: }
402:
403: public void visitAnyParameterAnnotationsAttribute(
404: Clazz clazz,
405: Method method,
406: ParameterAnnotationsAttribute parameterAnnotationsAttribute) {
407: // Write the parameter annotations.
408: dataOutput
409: .writeByte(parameterAnnotationsAttribute.u2parametersCount);
410:
411: for (int parameterIndex = 0; parameterIndex < parameterAnnotationsAttribute.u2parametersCount; parameterIndex++) {
412: // Write the parameter annotations of the given parameter.
413: int u2annotationsCount = parameterAnnotationsAttribute.u2parameterAnnotationsCount[parameterIndex];
414: Annotation[] annotations = parameterAnnotationsAttribute.parameterAnnotations[parameterIndex];
415:
416: dataOutput.writeShort(u2annotationsCount);
417:
418: for (int index = 0; index < u2annotationsCount; index++) {
419: Annotation annotation = annotations[index];
420: this .visitAnnotation(clazz, annotation);
421: }
422:
423: }
424: }
425:
426: public void visitAnnotationDefaultAttribute(Clazz clazz,
427: Method method,
428: AnnotationDefaultAttribute annotationDefaultAttribute) {
429: // Write the default element value.
430: annotationDefaultAttribute.defaultValue.accept(clazz, null,
431: this );
432: }
433:
434: // Implementations for InnerClassesInfoVisitor.
435:
436: public void visitInnerClassesInfo(Clazz clazz,
437: InnerClassesInfo innerClassesInfo) {
438: dataOutput.writeShort(innerClassesInfo.u2innerClassIndex);
439: dataOutput.writeShort(innerClassesInfo.u2outerClassIndex);
440: dataOutput.writeShort(innerClassesInfo.u2innerNameIndex);
441: dataOutput
442: .writeShort(innerClassesInfo.u2innerClassAccessFlags);
443: }
444:
445: // Implementations for ExceptionInfoVisitor.
446:
447: public void visitExceptionInfo(Clazz clazz, Method method,
448: CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) {
449: dataOutput.writeShort(exceptionInfo.u2startPC);
450: dataOutput.writeShort(exceptionInfo.u2endPC);
451: dataOutput.writeShort(exceptionInfo.u2handlerPC);
452: dataOutput.writeShort(exceptionInfo.u2catchType);
453: }
454:
455: // Implementations for StackMapFrameVisitor.
456:
457: public void visitAnyStackMapFrame(Clazz clazz, Method method,
458: CodeAttribute codeAttribute, int offset,
459: StackMapFrame stackMapFrame) {
460: // Write the stack map frame tag.
461: dataOutput.writeByte(stackMapFrame.getTag());
462:
463: // Write the actual body.
464: stackMapFrame.accept(clazz, method, codeAttribute, offset,
465: stackMapFrameBodyWriter);
466: }
467:
468: // Implementations for LineNumberInfoVisitor.
469:
470: public void visitLineNumberInfo(Clazz clazz, Method method,
471: CodeAttribute codeAttribute,
472: LineNumberInfo lineNumberInfo) {
473: dataOutput.writeShort(lineNumberInfo.u2startPC);
474: dataOutput.writeShort(lineNumberInfo.u2lineNumber);
475: }
476:
477: // Implementations for LocalVariableInfoVisitor.
478:
479: public void visitLocalVariableInfo(Clazz clazz, Method method,
480: CodeAttribute codeAttribute,
481: LocalVariableInfo localVariableInfo) {
482: dataOutput.writeShort(localVariableInfo.u2startPC);
483: dataOutput.writeShort(localVariableInfo.u2length);
484: dataOutput.writeShort(localVariableInfo.u2nameIndex);
485: dataOutput.writeShort(localVariableInfo.u2descriptorIndex);
486: dataOutput.writeShort(localVariableInfo.u2index);
487: }
488:
489: // Implementations for LocalVariableTypeInfoVisitor.
490:
491: public void visitLocalVariableTypeInfo(Clazz clazz,
492: Method method, CodeAttribute codeAttribute,
493: LocalVariableTypeInfo localVariableTypeInfo) {
494: dataOutput.writeShort(localVariableTypeInfo.u2startPC);
495: dataOutput.writeShort(localVariableTypeInfo.u2length);
496: dataOutput.writeShort(localVariableTypeInfo.u2nameIndex);
497: dataOutput
498: .writeShort(localVariableTypeInfo.u2signatureIndex);
499: dataOutput.writeShort(localVariableTypeInfo.u2index);
500: }
501:
502: // Implementations for AnnotationVisitor.
503:
504: public void visitAnnotation(Clazz clazz, Annotation annotation) {
505: // Write the annotation type.
506: dataOutput.writeShort(annotation.u2typeIndex);
507:
508: // Write the element value pairs.
509: dataOutput.writeShort(annotation.u2elementValuesCount);
510:
511: annotation.elementValuesAccept(clazz, this );
512: }
513:
514: // Implementations for ElementValueVisitor.
515:
516: public void visitAnyElementValue(Clazz clazz,
517: Annotation annotation, ElementValue elementValue) {
518: // Write the element name index, if applicable.
519: int u2elementNameIndex = elementValue.u2elementNameIndex;
520: if (u2elementNameIndex != 0) {
521: dataOutput.writeShort(u2elementNameIndex);
522: }
523:
524: // Write the tag.
525: dataOutput.writeByte(elementValue.getTag());
526:
527: // Write the actual body.
528: elementValue.accept(clazz, annotation,
529: elementValueBodyWriter);
530: }
531: }
532:
533: private class StackMapFrameBodyWriter extends SimplifiedVisitor
534: implements StackMapFrameVisitor, VerificationTypeVisitor {
535: public void visitSameZeroFrame(Clazz clazz, Method method,
536: CodeAttribute codeAttribute, int offset,
537: SameZeroFrame sameZeroFrame) {
538: if (sameZeroFrame.getTag() == StackMapFrame.SAME_ZERO_FRAME_EXTENDED) {
539: dataOutput.writeShort(sameZeroFrame.u2offsetDelta);
540: }
541: }
542:
543: public void visitSameOneFrame(Clazz clazz, Method method,
544: CodeAttribute codeAttribute, int offset,
545: SameOneFrame sameOneFrame) {
546: if (sameOneFrame.getTag() == StackMapFrame.SAME_ONE_FRAME_EXTENDED) {
547: dataOutput.writeShort(sameOneFrame.u2offsetDelta);
548: }
549:
550: // Write the verification type of the stack entry.
551: sameOneFrame.stackItemAccept(clazz, method, codeAttribute,
552: offset, this );
553: }
554:
555: public void visitLessZeroFrame(Clazz clazz, Method method,
556: CodeAttribute codeAttribute, int offset,
557: LessZeroFrame lessZeroFrame) {
558: dataOutput.writeShort(lessZeroFrame.u2offsetDelta);
559: }
560:
561: public void visitMoreZeroFrame(Clazz clazz, Method method,
562: CodeAttribute codeAttribute, int offset,
563: MoreZeroFrame moreZeroFrame) {
564: dataOutput.writeShort(moreZeroFrame.u2offsetDelta);
565:
566: // Write the verification types of the additional local variables.
567: moreZeroFrame.additionalVariablesAccept(clazz, method,
568: codeAttribute, offset, this );
569: }
570:
571: public void visitFullFrame(Clazz clazz, Method method,
572: CodeAttribute codeAttribute, int offset,
573: FullFrame fullFrame) {
574: dataOutput.writeShort(fullFrame.u2offsetDelta);
575:
576: // Write the verification types of the local variables.
577: dataOutput.writeShort(fullFrame.variablesCount);
578: fullFrame.variablesAccept(clazz, method, codeAttribute,
579: offset, this );
580:
581: // Write the verification types of the stack entries.
582: dataOutput.writeShort(fullFrame.stackCount);
583: fullFrame.stackAccept(clazz, method, codeAttribute, offset,
584: this );
585: }
586:
587: // Implementations for VerificationTypeVisitor.
588:
589: public void visitAnyVerificationType(Clazz clazz,
590: Method method, CodeAttribute codeAttribute, int offset,
591: VerificationType verificationType) {
592: // Write the verification type tag.
593: dataOutput.writeByte(verificationType.getTag());
594:
595: // Write the actual body.
596: verificationType.accept(clazz, method, codeAttribute,
597: offset, verificationTypeBodyWriter);
598: }
599: }
600:
601: private class VerificationTypeBodyWriter extends SimplifiedVisitor
602: implements VerificationTypeVisitor {
603: // Implementations for VerificationTypeVisitor.
604:
605: public void visitAnyVerificationType(Clazz clazz,
606: Method method, CodeAttribute codeAttribute, int offset,
607: VerificationType verificationType) {
608: // Most verification types don't contain any additional information.
609: }
610:
611: public void visitObjectType(Clazz clazz, Method method,
612: CodeAttribute codeAttribute, int offset,
613: ObjectType objectType) {
614: dataOutput.writeShort(objectType.u2classIndex);
615: }
616:
617: public void visitUninitializedType(Clazz clazz, Method method,
618: CodeAttribute codeAttribute, int offset,
619: UninitializedType uninitializedType) {
620: dataOutput
621: .writeShort(uninitializedType.u2newInstructionOffset);
622: }
623: }
624:
625: private class ElementValueBodyWriter extends SimplifiedVisitor
626: implements ElementValueVisitor {
627: // Implementations for ElementValueVisitor.
628:
629: public void visitConstantElementValue(Clazz clazz,
630: Annotation annotation,
631: ConstantElementValue constantElementValue) {
632: dataOutput
633: .writeShort(constantElementValue.u2constantValueIndex);
634: }
635:
636: public void visitEnumConstantElementValue(Clazz clazz,
637: Annotation annotation,
638: EnumConstantElementValue enumConstantElementValue) {
639: dataOutput
640: .writeShort(enumConstantElementValue.u2typeNameIndex);
641: dataOutput
642: .writeShort(enumConstantElementValue.u2constantNameIndex);
643: }
644:
645: public void visitClassElementValue(Clazz clazz,
646: Annotation annotation,
647: ClassElementValue classElementValue) {
648: dataOutput.writeShort(classElementValue.u2classInfoIndex);
649: }
650:
651: public void visitAnnotationElementValue(Clazz clazz,
652: Annotation annotation,
653: AnnotationElementValue annotationElementValue) {
654: // Write the annotation.
655: attributeBodyWriter.visitAnnotation(clazz,
656: annotationElementValue.annotationValue);
657: }
658:
659: public void visitArrayElementValue(Clazz clazz,
660: Annotation annotation,
661: ArrayElementValue arrayElementValue) {
662: // Write the element values.
663: dataOutput
664: .writeShort(arrayElementValue.u2elementValuesCount);
665:
666: arrayElementValue.elementValuesAccept(clazz, annotation,
667: attributeBodyWriter);
668: }
669: }
670: }
|