1 /* 2 * Copyright 2012, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package org.jf.dexlib2.util; 33 34 import org.jf.dexlib2.iface.reference.*; 35 import org.jf.util.StringUtils; 36 37 import javax.annotation.Nonnull; 38 import javax.annotation.Nullable; 39 import java.io.IOException; 40 import java.io.Writer; 41 42 public final class ReferenceUtil { 43 public static String getMethodDescriptor(MethodReference methodReference) { 44 return getMethodDescriptor(methodReference, false); 45 } 46 47 public static String getMethodDescriptor(MethodReference methodReference, boolean useImplicitReference) { 48 StringBuilder sb = new StringBuilder(); 49 if (!useImplicitReference) { 50 sb.append(methodReference.getDefiningClass()); 51 sb.append("->"); 52 } 53 sb.append(methodReference.getName()); 54 sb.append('('); 55 for (CharSequence paramType: methodReference.getParameterTypes()) { 56 sb.append(paramType); 57 } 58 sb.append(')'); 59 sb.append(methodReference.getReturnType()); 60 return sb.toString(); 61 } 62 63 public static void writeMethodDescriptor(Writer writer, MethodReference methodReference) throws IOException { 64 writeMethodDescriptor(writer, methodReference, false); 65 } 66 67 public static void writeMethodDescriptor(Writer writer, MethodReference methodReference, 68 boolean useImplicitReference) throws IOException { 69 if (!useImplicitReference) { 70 writer.write(methodReference.getDefiningClass()); 71 writer.write("->"); 72 } 73 writer.write(methodReference.getName()); 74 writer.write('('); 75 for (CharSequence paramType: methodReference.getParameterTypes()) { 76 writer.write(paramType.toString()); 77 } 78 writer.write(')'); 79 writer.write(methodReference.getReturnType()); 80 } 81 82 public static String getFieldDescriptor(FieldReference fieldReference) { 83 return getFieldDescriptor(fieldReference, false); 84 } 85 86 public static String getFieldDescriptor(FieldReference fieldReference, boolean useImplicitReference) { 87 StringBuilder sb = new StringBuilder(); 88 if (!useImplicitReference) { 89 sb.append(fieldReference.getDefiningClass()); 90 sb.append("->"); 91 } 92 sb.append(fieldReference.getName()); 93 sb.append(':'); 94 sb.append(fieldReference.getType()); 95 return sb.toString(); 96 } 97 98 public static String getShortFieldDescriptor(FieldReference fieldReference) { 99 StringBuilder sb = new StringBuilder(); 100 sb.append(fieldReference.getName()); 101 sb.append(':'); 102 sb.append(fieldReference.getType()); 103 return sb.toString(); 104 } 105 106 public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference) throws IOException { 107 writeFieldDescriptor(writer, fieldReference, false); 108 } 109 110 public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference, 111 boolean implicitReference) throws IOException { 112 if (!implicitReference) { 113 writer.write(fieldReference.getDefiningClass()); 114 writer.write("->"); 115 } 116 writer.write(fieldReference.getName()); 117 writer.write(':'); 118 writer.write(fieldReference.getType()); 119 } 120 121 @Nullable 122 public static String getReferenceString(@Nonnull Reference reference) { 123 return getReferenceString(reference, null); 124 } 125 126 @Nullable 127 public static String getReferenceString(@Nonnull Reference reference, @Nullable String containingClass) { 128 if (reference instanceof StringReference) { 129 return String.format("\"%s\"", StringUtils.escapeString(((StringReference)reference).getString())); 130 } 131 if (reference instanceof TypeReference) { 132 return ((TypeReference)reference).getType(); 133 } 134 if (reference instanceof FieldReference) { 135 FieldReference fieldReference = (FieldReference)reference; 136 boolean useImplicitReference = fieldReference.getDefiningClass().equals(containingClass); 137 return getFieldDescriptor((FieldReference)reference, useImplicitReference); 138 } 139 if (reference instanceof MethodReference) { 140 MethodReference methodReference = (MethodReference)reference; 141 boolean useImplicitReference = methodReference.getDefiningClass().equals(containingClass); 142 return getMethodDescriptor((MethodReference)reference, useImplicitReference); 143 } 144 return null; 145 } 146 147 private ReferenceUtil() {} 148 } 149