/** * Returns the argument types of methods of this type. This method should only be used for method * types. * * @return the argument types of methods of this type. */ public Type[] getArgumentTypes() { return getArgumentTypes(getDescriptor()); }
/** * Returns the {@link Type} corresponding to the given method descriptor. Equivalent to <code> * Type.getType(methodDescriptor)</code>. * * @param methodDescriptor a method descriptor. * @return the {@link Type} corresponding to the given method descriptor. */ public static Type getMethodType(final String methodDescriptor) { return new Type(METHOD, methodDescriptor, 0, methodDescriptor.length()); }
/** * Returns the descriptor corresponding to the given class. * * @param clazz an object class, a primitive class or an array class. * @return the descriptor corresponding to the given class. */ public static String getDescriptor(final Class<?> clazz) { StringBuilder stringBuilder = new StringBuilder(); appendDescriptor(clazz, stringBuilder); return stringBuilder.toString(); }
/** * Returns the return type of methods of this type. This method should only be used for method * types. * * @return the return type of methods of this type. */ public Type getReturnType() { return getReturnType(getDescriptor()); }
/** * Returns the type of the elements of this array type. This method should only be used for an * array type. * * @return Returns the type of the elements of this array type. */ public Type getElementType() { final int numDimensions = getDimensions(); return getTypeInternal(valueBuffer, valueBegin + numDimensions, valueEnd); }
} else if (value instanceof Type) { Type type = (Type) value; int typeSort = type.getSort(); if (typeSort == Type.OBJECT) { return addConstantClass(type.getInternalName()); } else if (typeSort == Type.METHOD) { return addConstantMethodType(type.getDescriptor()); } else { // type is a primitive or array type. return addConstantClass(type.getDescriptor());
return "double"; case ARRAY: StringBuilder stringBuilder = new StringBuilder(getElementType().getClassName()); for (int i = getDimensions(); i > 0; --i) { stringBuilder.append("[]");
/** * Returns the size of the arguments and of the return value of methods of this type. This method * should only be used for method types. * * @return the size of the arguments of the method (plus one for the implicit this argument), * argumentsSize, and the size of its return value, returnSize, packed into a single int i = * {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code * i >> 2}, and returnSize to {@code i & 0x03}). */ public int getArgumentsAndReturnSizes() { return getArgumentsAndReturnSizes(getDescriptor()); }
/** * Returns the abstract type corresponding to the given public API frame element type. * * @param symbolTable the type table to use to lookup and store type {@link Symbol}. * @param type a frame element type described using the same format as in {@link * MethodVisitor#visitFrame}, i.e. either {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL}, or * {@link Opcodes#UNINITIALIZED_THIS}, or the internal name of a class, or a Label designating * a NEW instruction (for uninitialized types). * @return the abstract type corresponding to the given frame element type. */ static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Object type) { if (type instanceof Integer) { return CONSTANT_KIND | ((Integer) type).intValue(); } else if (type instanceof String) { String descriptor = Type.getObjectType((String) type).getDescriptor(); return getAbstractTypeFromDescriptor(symbolTable, descriptor, 0); } else { return UNINITIALIZED_KIND | symbolTable.addUninitializedType("", ((Label) type).bytecodeOffset); } }
return getType(getDescriptor(clazz));
/** * Returns a string representation of this type. * * @return the descriptor of this type. */ @Override public String toString() { return getDescriptor(); } }
/** * Returns the method {@link Type} corresponding to the given constructor. * * @param constructor a {@link Constructor} object. * @return the method {@link Type} corresponding to the given constructor. */ public static Type getType(final Constructor<?> constructor) { return getType(getConstructorDescriptor(constructor)); }
/** * Returns the result {@link Type#getArgumentsAndReturnSizes} on {@link #value}. * * @return the result {@link Type#getArgumentsAndReturnSizes} on {@link #value} (memoized in * {@link #info} for efficiency). This should only be used for {@link * #CONSTANT_METHODREF_TAG}, {@link #CONSTANT_INTERFACE_METHODREF_TAG} and {@link * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols. */ int getArgumentsAndReturnSizes() { if (info == 0) { info = Type.getArgumentsAndReturnSizes(value); } return info; } }
@Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { if (paramExtractor != null) { return null; // method already found, skip all further methods } if (!name.equals(methodName)) { return null; // different method } Type[] argumentTypes = Type.getArgumentTypes(desc); int dwordsCount = 0; for (Type t : argumentTypes) { if (t.getClassName().equals(TYPE_LONG) || t.getClassName().equals(TYPE_DOUBLE)) { dwordsCount++; } } int paramCount = argumentTypes.length; if (paramCount != this.parameterTypes.length) { return null; // different number of params } for (int i = 0; i < argumentTypes.length; i++) { if (!isEqualTypeName(argumentTypes[i], this.parameterTypes[i])) { return null; // wrong param types } } this.paramExtractor = new ParamExtractor((Modifier.isStatic(access) ? 0 : 1), argumentTypes.length + dwordsCount); return paramExtractor; }
/** * Returns <code>true</code> if type name equals param type. */ boolean isEqualTypeName(final Type argumentType, final Class paramType) { String s = argumentType.getClassName(); if (s.endsWith(ARRAY)) { // arrays detected String prefix = s.substring(0, s.length() - 2); String bytecodeSymbol = primitives.get(prefix); if (bytecodeSymbol != null) { s = '[' + bytecodeSymbol; } else { s = "[L" + prefix + ';'; } } return s.equals(paramType.getName()); }
@Override public AnnotationVisitor visitParameterAnnotation( final int parameter, final String annotationDescriptor, final boolean visible) { // Create a ByteVector to hold an 'annotation' JVMS structure. // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16. ByteVector annotation = new ByteVector(); // Write type_index and reserve space for num_element_value_pairs. annotation.putShort(symbolTable.addConstantUtf8(annotationDescriptor)).putShort(0); if (visible) { if (lastRuntimeVisibleParameterAnnotations == null) { lastRuntimeVisibleParameterAnnotations = new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; } return lastRuntimeVisibleParameterAnnotations[parameter] = new AnnotationWriter( symbolTable, annotation, lastRuntimeVisibleParameterAnnotations[parameter]); } else { if (lastRuntimeInvisibleParameterAnnotations == null) { lastRuntimeInvisibleParameterAnnotations = new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; } return lastRuntimeInvisibleParameterAnnotations[parameter] = new AnnotationWriter( symbolTable, annotation, lastRuntimeInvisibleParameterAnnotations[parameter]); } }
} else if (value instanceof Type) { Type type = (Type) value; int typeSort = type.getSort(); if (typeSort == Type.OBJECT) { return addConstantClass(type.getInternalName()); } else if (typeSort == Type.METHOD) { return addConstantMethodType(type.getDescriptor()); } else { // type is a primitive or array type. return addConstantClass(type.getDescriptor());
return "double"; case ARRAY: StringBuilder stringBuilder = new StringBuilder(getElementType().getClassName()); for (int i = getDimensions(); i > 0; --i) { stringBuilder.append("[]");
/** * Returns the return type of methods of this type. This method should only be used for method * types. * * @return the return type of methods of this type. */ public Type getReturnType() { return getReturnType(getDescriptor()); }
/** * Returns the size of the arguments and of the return value of methods of this type. This method * should only be used for method types. * * @return the size of the arguments of the method (plus one for the implicit this argument), * argumentsSize, and the size of its return value, returnSize, packed into a single int i = * {@code (argumentsSize << 2) | returnSize} (argumentsSize is therefore equal to {@code * i >> 2}, and returnSize to {@code i & 0x03}). */ public int getArgumentsAndReturnSizes() { return getArgumentsAndReturnSizes(getDescriptor()); }