/** * Returns a constant {@code null} value of type {@link Object}. * * @return A dynamically resolved null constant. */ public static Dynamic ofNullConstant() { return new Dynamic(new ConstantDynamic("nullConstant", TypeDescription.OBJECT.getDescriptor(), new Handle(Opcodes.H_INVOKESTATIC, CONSTANT_BOOTSTRAPS, "nullConstant", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;", false)), TypeDescription.OBJECT); }
/** * Returns a {@link Class} constant for a primitive type. * * @param typeDescription The primitive type to represent. * @return A dynamically resolved primitive type constant. */ public static JavaConstant ofPrimitiveType(TypeDescription typeDescription) { if (!typeDescription.isPrimitive()) { throw new IllegalArgumentException("Not a primitive type: " + typeDescription); } return new Dynamic(new ConstantDynamic(typeDescription.getDescriptor(), TypeDescription.CLASS.getDescriptor(), new Handle(Opcodes.H_INVOKESTATIC, CONSTANT_BOOTSTRAPS, "primitiveClass", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;", false)), TypeDescription.CLASS); }
/** * Returns a {@link Enum} value constant. * * @param enumerationDescription The enumeration value to represent. * @return A dynamically resolved enumeration constant. */ public static JavaConstant ofEnumeration(EnumerationDescription enumerationDescription) { return new Dynamic(new ConstantDynamic(enumerationDescription.getValue(), enumerationDescription.getEnumerationType().getDescriptor(), new Handle(Opcodes.H_INVOKESTATIC, CONSTANT_BOOTSTRAPS, "enumConstant", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Enum;", false)), enumerationDescription.getEnumerationType()); }
/** * Resolves a var handle constant for an array. * * @param typeDescription The array type for which the var handle is resolved. * @return A dynamic constant that represents the created var handle constant. */ public static JavaConstant ofArrayVarHandle(TypeDescription typeDescription) { if (!typeDescription.isArray()) { throw new IllegalArgumentException("Not an array type: " + typeDescription); } return new Dynamic(new ConstantDynamic("arrayVarHandle", JavaType.VAR_HANDLE.getTypeStub().getDescriptor(), new Handle(Opcodes.H_INVOKESTATIC, CONSTANT_BOOTSTRAPS, "arrayVarHandle", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;", false), Type.getType(typeDescription.getDescriptor())), JavaType.VAR_HANDLE.getTypeStub()); }
/** * Resolves this {@link Dynamic} constant to resolve the returned instance to the supplied type. The type must be a subtype of the * bootstrap method's return type. Constructors cannot be resolved to a different type. * * @param typeDescription The type to resolve the bootstrapped value to. * @return This dynamic constant but resolved to the supplied type. */ public JavaConstant withType(TypeDescription typeDescription) { if (typeDescription.represents(void.class)) { throw new IllegalArgumentException("Constant value cannot represent void"); } else if (value.getBootstrapMethod().getName().equals(MethodDescription.CONSTRUCTOR_INTERNAL_NAME) ? !this.typeDescription.isAssignableTo(typeDescription) : (!typeDescription.asBoxed().isInHierarchyWith(this.typeDescription.asBoxed()))) { throw new IllegalArgumentException(typeDescription + " is not compatible with bootstrapped type " + this.typeDescription); } Object[] bootstrapMethodArgument = new Object[value.getBootstrapMethodArgumentCount()]; for (int index = 0; index < value.getBootstrapMethodArgumentCount(); index++) { bootstrapMethodArgument[index] = value.getBootstrapMethodArgument(index); } return new Dynamic(new ConstantDynamic(value.getName(), typeDescription.getDescriptor(), value.getBootstrapMethod(), bootstrapMethodArgument), typeDescription); }
return new Dynamic(new ConstantDynamic(name, (bootstrapMethod.isConstructor() ? bootstrapMethod.getDeclaringType()
/** * Reads a CONSTANT_Dynamic constant pool entry in {@link #b}. * * @param constantPoolEntryIndex the index of a CONSTANT_Dynamic entry in the class's constant * pool table. * @param charBuffer the buffer to be used to read the string. This buffer must be sufficiently * large. It is not automatically resized. * @return the ConstantDynamic corresponding to the specified CONSTANT_Dynamic entry. */ private ConstantDynamic readConstantDynamic( final int constantPoolEntryIndex, final char[] charBuffer) { ConstantDynamic constantDynamic = constantDynamicValues[constantPoolEntryIndex]; if (constantDynamic != null) { return constantDynamic; } int cpInfoOffset = cpInfoOffsets[constantPoolEntryIndex]; int nameAndTypeCpInfoOffset = cpInfoOffsets[readUnsignedShort(cpInfoOffset + 2)]; String name = readUTF8(nameAndTypeCpInfoOffset, charBuffer); String descriptor = readUTF8(nameAndTypeCpInfoOffset + 2, charBuffer); int bootstrapMethodOffset = bootstrapMethodOffsets[readUnsignedShort(cpInfoOffset)]; Handle handle = (Handle) readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer); Object[] bootstrapMethodArguments = new Object[readUnsignedShort(bootstrapMethodOffset + 2)]; bootstrapMethodOffset += 4; for (int i = 0; i < bootstrapMethodArguments.length; i++) { bootstrapMethodArguments[i] = readConst(readUnsignedShort(bootstrapMethodOffset), charBuffer); bootstrapMethodOffset += 2; } return constantDynamicValues[constantPoolEntryIndex] = new ConstantDynamic(name, descriptor, handle, bootstrapMethodArguments); }
return new Dynamic(new ConstantDynamic("invoke", (methodDescription.isConstructor() ? methodDescription.getDeclaringType()