Home | History | Annotate | Download | only in util
      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