package scouter.bytebuddy.description;
import scouter.bytebuddy.description.field.FieldDescription;
import scouter.bytebuddy.description.method.MethodDescription;
import scouter.bytebuddy.description.method.ParameterDescription;
import scouter.bytebuddy.description.modifier.*;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.jar.asm.Opcodes;
/**
* Implementations of this interface can be described in terms of a Java modifier.
*/
public interface ModifierReviewable {
/**
* Representation of the default modifier.
*/
int EMPTY_MASK = 0;
/**
* Returns the modifier that is described by this object.
*
* @return The modifier that is described by this object.
*/
int getModifiers();
/**
* Specifies if the modifier described by this object is {@code final}.
*
* @return {@code true} if the modifier described by this object is {@code final}.
*/
boolean isFinal();
/**
* Specifies if the modifier described by this object is synthetic.
*
* @return {@code true} if the modifier described by this object is synthetic.
*/
boolean isSynthetic();
/**
* Returns this objects synthetic state.
*
* @return This objects synthetic state.
*/
SyntheticState getSyntheticState();
/**
* A modifier reviewable for a {@link ByteCodeElement}, i.e. a type, a field or a method.
*/
interface OfByteCodeElement extends ModifierReviewable {
/**
* Specifies if the modifier described by this object is {@code public}.
*
* @return {@code true} if the modifier described by this object is {@code public}.
*/
boolean isPublic();
/**
* Specifies if the modifier described by this object is {@code protected}.
*
* @return {@code true} if the modifier described by this object is {@code protected}.
*/
boolean isProtected();
/**
* Specifies if the modifier described by this object is package private.
*
* @return {@code true} if the modifier described by this object is package private.
*/
boolean isPackagePrivate();
/**
* Specifies if the modifier described by this object is {@code private}.
*
* @return {@code true} if the modifier described by this object is {@code private}.
*/
boolean isPrivate();
/**
* Specifies if the modifier described by this object is {@code static}.
*
* @return {@code true} if the modifier described by this object is {@code static}.
*/
boolean isStatic();
/**
* Specifies if the modifier described by this object represents the deprecated flag.
*
* @return {@code true} if the modifier described by this object represents the deprecated flag.
*/
boolean isDeprecated();
/**
* Return's this byte code element's ownership.
*
* @return This byte code element's ownership.
*/
Ownership getOwnership();
/**
* Returns this byte code element's visibility.
*
* @return This byte code element's visibility.
*/
Visibility getVisibility();
}
/**
* A modifier reviewable for a byte code element that can be abstract, i.e. a {@link TypeDescription}
* or a {@link MethodDescription}.
*/
interface OfAbstraction extends OfByteCodeElement {
/**
* Specifies if the modifier described by this object is {@code abstract}.
*
* @return {@code true} if the modifier described by this object is {@code abstract}.
*/
boolean isAbstract();
}
/**
* A modifier reviewable for a byte code element that can represent an enumeration, i.e. a {@link FieldDescription}
* that holds an enumeration value or a {@link TypeDescription} that represents an enumeration.
*/
interface OfEnumeration extends OfByteCodeElement {
/**
* Specifies if the modifier described by this object represents the enum flag.
*
* @return {@code true} if the modifier described by this object represents the enum flag.
*/
boolean isEnum();
/**
* Returns this byte code element's enumeration state.
*
* @return This byte code element's enumeration state.
*/
EnumerationState getEnumerationState();
}
/**
* A modifier reviewable for a {@link TypeDescription}.
*/
interface ForTypeDefinition extends OfAbstraction, OfEnumeration {
/**
* Specifies if the modifier described by this object represents the interface flag.
*
* @return {@code true} if the modifier described by this object represents the interface flag.
*/
boolean isInterface();
/**
* Specifies if the modifier described by this object represents the annotation flag.
*
* @return {@code true} if the modifier described by this object represents the annotation flag.
*/
boolean isAnnotation();
/**
* Returns this type's manifestation.
*
* @return This type's manifestation.
*/
TypeManifestation getTypeManifestation();
}
/**
* A modifier reviewable for a {@link FieldDescription}.
*/
interface ForFieldDescription extends OfEnumeration {
/**
* Specifies if the modifier described by this object represents the volatile flag.
*
* @return {@code true} if the modifier described by this object represents the volatile flag.
*/
boolean isVolatile();
/**
* Specifies if the modifier described by this object represents the transient flag.
*
* @return {@code true} if the modifier described by this object represents the transient flag.
*/
boolean isTransient();
/**
* Returns this field's manifestation.
*
* @return This field's manifestation.
*/
FieldManifestation getFieldManifestation();
}
/**
* A modifier reviewable for a {@link MethodDescription}.
*/
interface ForMethodDescription extends OfAbstraction {
/**
* Specifies if the modifier described by this object is {@code synchronized}.
*
* @return {@code true} if the modifier described by this object is {@code synchronized}.
*/
boolean isSynchronized();
/**
* Specifies if the modifier described by this object represents the var args flag.
*
* @return {@code true} if the modifier described by this object represents the var args flag.
*/
boolean isVarArgs();
/**
* Specifies if the modifier described by this object is {@code native}.
*
* @return {@code true} if the modifier described by this object is {@code native}.
*/
boolean isNative();
/**
* Specifies if the modifier described by this object represents the bridge flag.
*
* @return {@code true} if the modifier described by this object represents the bridge flag
*/
boolean isBridge();
/**
* Specifies if the modifier described by this object is {@code strictfp}.
*
* @return {@code true} if the modifier described by this object is {@code strictfp}.
*/
boolean isStrict();
/**
* Returns this method's synchronization state.
*
* @return This method's synchronization state.
*/
SynchronizationState getSynchronizationState();
/**
* Returns this method's strictness in floating-point computation.
*
* @return This method's strictness in floating-point computation.
*/
MethodStrictness getMethodStrictness();
/**
* Returns this method's manifestation.
*
* @return This method's manifestation.
*/
MethodManifestation getMethodManifestation();
}
/**
* A modifier reviewable for a {@link ParameterDescription}.
*/
interface ForParameterDescription extends ModifierReviewable {
/**
* CSpecifies if the modifier described by this object is mandated.
*
* @return {@code true} if the modifier described by this object is mandated.
*/
boolean isMandated();
/**
* Returns this parameter's manifestation.
*
* @return This parameter's manifestation.
*/
ParameterManifestation getParameterManifestation();
/**
* Returns this parameter's provisioning state.
*
* @return This parameter's provisioning state.
*/
ProvisioningState getProvisioningState();
}
/**
* An abstract base implementation of a {@link ModifierReviewable} class.
*/
abstract class AbstractBase implements ForTypeDefinition, ForFieldDescription, ForMethodDescription, ForParameterDescription {
@Override
public boolean isAbstract() {
return matchesMask(Opcodes.ACC_ABSTRACT);
}
@Override
public boolean isFinal() {
return matchesMask(Opcodes.ACC_FINAL);
}
@Override
public boolean isStatic() {
return matchesMask(Opcodes.ACC_STATIC);
}
@Override
public boolean isPublic() {
return matchesMask(Opcodes.ACC_PUBLIC);
}
@Override
public boolean isProtected() {
return matchesMask(Opcodes.ACC_PROTECTED);
}
@Override
public boolean isPackagePrivate() {
return !isPublic() && !isProtected() && !isPrivate();
}
@Override
public boolean isPrivate() {
return matchesMask(Opcodes.ACC_PRIVATE);
}
@Override
public boolean isNative() {
return matchesMask(Opcodes.ACC_NATIVE);
}
@Override
public boolean isSynchronized() {
return matchesMask(Opcodes.ACC_SYNCHRONIZED);
}
@Override
public boolean isStrict() {
return matchesMask(Opcodes.ACC_STRICT);
}
@Override
public boolean isMandated() {
return matchesMask(Opcodes.ACC_MANDATED);
}
@Override
public boolean isSynthetic() {
return matchesMask(Opcodes.ACC_SYNTHETIC);
}
@Override
public boolean isBridge() {
return matchesMask(Opcodes.ACC_BRIDGE);
}
@Override
public boolean isDeprecated() {
return matchesMask(Opcodes.ACC_DEPRECATED);
}
@Override
public boolean isAnnotation() {
return matchesMask(Opcodes.ACC_ANNOTATION);
}
@Override
public boolean isEnum() {
return matchesMask(Opcodes.ACC_ENUM);
}
@Override
public boolean isInterface() {
return matchesMask(Opcodes.ACC_INTERFACE);
}
@Override
public boolean isTransient() {
return matchesMask(Opcodes.ACC_TRANSIENT);
}
@Override
public boolean isVolatile() {
return matchesMask(Opcodes.ACC_VOLATILE);
}
@Override
public boolean isVarArgs() {
return matchesMask(Opcodes.ACC_VARARGS);
}
@Override
public SyntheticState getSyntheticState() {
return isSynthetic()
? SyntheticState.SYNTHETIC
: SyntheticState.PLAIN;
}
@Override
public Visibility getVisibility() {
int modifiers = getModifiers();
switch (modifiers & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE)) {
case Opcodes.ACC_PUBLIC:
return Visibility.PUBLIC;
case Opcodes.ACC_PROTECTED:
return Visibility.PROTECTED;
case EMPTY_MASK:
return Visibility.PACKAGE_PRIVATE;
case Opcodes.ACC_PRIVATE:
return Visibility.PRIVATE;
default:
throw new IllegalStateException("Unexpected modifiers: " + modifiers);
}
}
@Override
public Ownership getOwnership() {
return isStatic()
? Ownership.STATIC
: Ownership.MEMBER;
}
@Override
public EnumerationState getEnumerationState() {
return isEnum()
? EnumerationState.ENUMERATION
: EnumerationState.PLAIN;
}
@Override
public TypeManifestation getTypeManifestation() {
int modifiers = getModifiers();
switch (modifiers & (Opcodes.ACC_ANNOTATION | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL)) {
case Opcodes.ACC_FINAL:
return TypeManifestation.FINAL;
case Opcodes.ACC_ABSTRACT:
return TypeManifestation.ABSTRACT;
case Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE:
return TypeManifestation.INTERFACE;
case Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE | Opcodes.ACC_ANNOTATION:
return TypeManifestation.ANNOTATION;
case EMPTY_MASK:
return TypeManifestation.PLAIN;
default:
throw new IllegalStateException("Unexpected modifiers: " + modifiers);
}
}
@Override
public FieldManifestation getFieldManifestation() {
int modifiers = getModifiers();
switch (modifiers & (Opcodes.ACC_VOLATILE | Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT)) {
case Opcodes.ACC_FINAL:
return FieldManifestation.FINAL;
case Opcodes.ACC_VOLATILE:
return FieldManifestation.VOLATILE;
case Opcodes.ACC_TRANSIENT:
return FieldManifestation.TRANSIENT;
case Opcodes.ACC_TRANSIENT | Opcodes.ACC_VOLATILE:
return FieldManifestation.VOLATILE_TRANSIENT;
case EMPTY_MASK:
return FieldManifestation.PLAIN;
default:
throw new IllegalStateException("Unexpected modifiers: " + modifiers);
}
}
@Override
public SynchronizationState getSynchronizationState() {
return isSynchronized()
? SynchronizationState.SYNCHRONIZED
: SynchronizationState.PLAIN;
}
@Override
public MethodManifestation getMethodManifestation() {
int modifiers = getModifiers();
switch (modifiers & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_BRIDGE)) {
case Opcodes.ACC_NATIVE | Opcodes.ACC_FINAL:
return MethodManifestation.FINAL_NATIVE;
case Opcodes.ACC_NATIVE:
return MethodManifestation.NATIVE;
case Opcodes.ACC_FINAL:
return MethodManifestation.FINAL;
case Opcodes.ACC_BRIDGE:
return MethodManifestation.BRIDGE;
case Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL:
return MethodManifestation.FINAL_BRIDGE;
case Opcodes.ACC_ABSTRACT:
return MethodManifestation.ABSTRACT;
case EMPTY_MASK:
return MethodManifestation.PLAIN;
default:
throw new IllegalStateException("Unexpected modifiers: " + modifiers);
}
}
@Override
public MethodStrictness getMethodStrictness() {
return isStrict()
? MethodStrictness.STRICT
: MethodStrictness.PLAIN;
}
@Override
public ParameterManifestation getParameterManifestation() {
return isFinal()
? ParameterManifestation.FINAL
: ParameterManifestation.PLAIN;
}
@Override
public ProvisioningState getProvisioningState() {
return isMandated()
? ProvisioningState.MANDATED
: ProvisioningState.PLAIN;
}
/**
* Checks if a mask is matched by this instance.
*
* @param mask The mask to check.
* @return {@code true} if the mask is matched.
*/
private boolean matchesMask(int mask) {
return (getModifiers() & mask) == mask;
}
}
}