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 String getMethodProtoDescriptor(MethodProtoReference methodProtoReference) { 64 StringBuilder sb = new StringBuilder(); 65 sb.append('('); 66 for (CharSequence paramType : methodProtoReference.getParameterTypes()) { 67 sb.append(paramType); 68 } 69 sb.append(')'); 70 sb.append(methodProtoReference.getReturnType()); 71 return sb.toString(); 72 } 73 74 public static void writeMethodDescriptor(Writer writer, MethodReference methodReference) throws IOException { 75 writeMethodDescriptor(writer, methodReference, false); 76 } 77 78 public static void writeMethodDescriptor(Writer writer, MethodReference methodReference, 79 boolean useImplicitReference) throws IOException { 80 if (!useImplicitReference) { 81 writer.write(methodReference.getDefiningClass()); 82 writer.write("->"); 83 } 84 writer.write(methodReference.getName()); 85 writer.write('('); 86 for (CharSequence paramType: methodReference.getParameterTypes()) { 87 writer.write(paramType.toString()); 88 } 89 writer.write(')'); 90 writer.write(methodReference.getReturnType()); 91 } 92 93 public static String getFieldDescriptor(FieldReference fieldReference) { 94 return getFieldDescriptor(fieldReference, false); 95 } 96 97 public static String getFieldDescriptor(FieldReference fieldReference, boolean useImplicitReference) { 98 StringBuilder sb = new StringBuilder(); 99 if (!useImplicitReference) { 100 sb.append(fieldReference.getDefiningClass()); 101 sb.append("->"); 102 } 103 sb.append(fieldReference.getName()); 104 sb.append(':'); 105 sb.append(fieldReference.getType()); 106 return sb.toString(); 107 } 108 109 public static String getShortFieldDescriptor(FieldReference fieldReference) { 110 StringBuilder sb = new StringBuilder(); 111 sb.append(fieldReference.getName()); 112 sb.append(':'); 113 sb.append(fieldReference.getType()); 114 return sb.toString(); 115 } 116 117 public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference) throws IOException { 118 writeFieldDescriptor(writer, fieldReference, false); 119 } 120 121 public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference, 122 boolean implicitReference) throws IOException { 123 if (!implicitReference) { 124 writer.write(fieldReference.getDefiningClass()); 125 writer.write("->"); 126 } 127 writer.write(fieldReference.getName()); 128 writer.write(':'); 129 writer.write(fieldReference.getType()); 130 } 131 132 @Nullable 133 public static String getReferenceString(@Nonnull Reference reference) { 134 return getReferenceString(reference, null); 135 } 136 137 @Nullable 138 public static String getReferenceString(@Nonnull Reference reference, @Nullable String containingClass) { 139 if (reference instanceof StringReference) { 140 return String.format("\"%s\"", StringUtils.escapeString(((StringReference)reference).getString())); 141 } 142 if (reference instanceof TypeReference) { 143 return ((TypeReference)reference).getType(); 144 } 145 if (reference instanceof FieldReference) { 146 FieldReference fieldReference = (FieldReference)reference; 147 boolean useImplicitReference = fieldReference.getDefiningClass().equals(containingClass); 148 return getFieldDescriptor(fieldReference, useImplicitReference); 149 } 150 if (reference instanceof MethodReference) { 151 MethodReference methodReference = (MethodReference)reference; 152 boolean useImplicitReference = methodReference.getDefiningClass().equals(containingClass); 153 return getMethodDescriptor(methodReference, useImplicitReference); 154 } 155 if (reference instanceof MethodProtoReference) { 156 MethodProtoReference methodProtoReference = (MethodProtoReference)reference; 157 return getMethodProtoDescriptor(methodProtoReference); 158 } 159 return null; 160 } 161 162 private ReferenceUtil() {} 163 } 164