Package co.cask.cdap.internal.asm

Source Code of co.cask.cdap.internal.asm.Signatures

/*
* Copyright © 2014 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package co.cask.cdap.internal.asm;

import com.google.common.reflect.TypeToken;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter;

import java.lang.reflect.ParameterizedType;

/**
* Util class for generating class signature.
*/
public final class Signatures {

  public static String getClassSignature(TypeToken<?> interfaceType) {
    SignatureWriter signWriter = new SignatureWriter();
    SignatureVisitor sv = signWriter.visitSuperclass();
    sv.visitClassType(Type.getInternalName(Object.class));
    sv.visitEnd();

    SignatureVisitor interfaceVisitor = sv.visitInterface();
    interfaceVisitor.visitClassType(Type.getInternalName(interfaceType.getRawType()));

    if (interfaceType.getType() instanceof ParameterizedType) {
      for (java.lang.reflect.Type paramType : ((ParameterizedType) interfaceType.getType()).getActualTypeArguments()) {
        interfaceVisitor.visitTypeArgument(SignatureVisitor.INSTANCEOF);
        visitTypeSignature(interfaceType.resolveType(paramType), interfaceVisitor);
      }
    }

    sv.visitEnd();
    return signWriter.toString();
  }

  /**
   * Generates signature for the given method.
   *
   * @param method Method that needs signature to be generated
   * @param types List of {@link TypeToken} that matches with the number of arguments in the given method.
   *              For a given method argument, if the coresponding {@link TypeToken} is non-null, it will be
   *              used to generate the type parameter in the signature, otherwise, the one in the method will be used.
   *              It's useful if the method is parameterized so that parameterize type information can be passed
   *              through the type tokens.
   * @return A method signature string
   */
  public static String getMethodSignature(Method method, TypeToken<?>...types) {
    SignatureWriter signWriter = new SignatureWriter();

    Type[] argumentTypes = method.getArgumentTypes();

    for (int i = 0; i < argumentTypes.length; i++) {
      SignatureVisitor sv = signWriter.visitParameterType();
      if (types[i] != null) {
        visitTypeSignature(types[i], sv);
      } else {
        sv.visitClassType(argumentTypes[i].getInternalName());
        sv.visitEnd();
      }
    }

    signWriter.visitReturnType().visitBaseType('V');

    return signWriter.toString();
  }


  public static String getFieldSignature(TypeToken<?> fieldType) {
    SignatureWriter signWriter = new SignatureWriter();
    signWriter.visitClassType(Type.getInternalName(fieldType.getRawType()));

    if (fieldType.getType() instanceof ParameterizedType) {
      for (java.lang.reflect.Type paramType : ((ParameterizedType) fieldType.getType()).getActualTypeArguments()) {
        signWriter.visitTypeArgument(SignatureVisitor.INSTANCEOF);
        visitTypeSignature(fieldType.resolveType(paramType), signWriter);
      }
    }
    signWriter.visitEnd();
    return signWriter.toString();
  }

  public static void visitTypeSignature(TypeToken<?> type, SignatureVisitor visitor) {
    Class<?> rawType = type.getRawType();
    if (rawType.isPrimitive()) {
      visitor.visitBaseType(Type.getType(rawType).toString().charAt(0));
      return;
    } else if (rawType.isArray()) {
      visitTypeSignature(type.getComponentType(), visitor.visitArrayType());
      return;
    } else {
      visitor.visitClassType(Type.getInternalName(rawType));
    }

    java.lang.reflect.Type visitType = type.getType();
    if (visitType instanceof ParameterizedType) {
      for (java.lang.reflect.Type argType : ((ParameterizedType) visitType).getActualTypeArguments()) {
        visitTypeSignature(TypeToken.of(argType), visitor.visitTypeArgument(SignatureVisitor.INSTANCEOF));
      }
    }

    visitor.visitEnd();
  }

  private Signatures() {}
}
TOP

Related Classes of co.cask.cdap.internal.asm.Signatures

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.