""" Java java.lang.annotation APIs implemented in Python. java.lang.annotation package - Annotation, Retention, Target, Documented, Inherited, etc. Desktop wrapper classes mirroring the Java annotation framework. """ from __future__ import annotations from .._core import Stub, AndroidOnlyError from ..java.lang import Error __all__ = [ "Annotation", "Documented", "Inherited", "Repeatable", "Retention", "RetentionPolicy", "Target", "ElementType", "Native", "IncompleteAnnotationException", "AnnotationFormatError", ] # ============================================================ # RetentionPolicy enum # ============================================================ class RetentionPolicy(Stub): """ java.lang.annotation.RetentionPolicy Enum-like class for annotation retention policies. """ SOURCE: "RetentionPolicy" = None CLASS: "RetentionPolicy" = None RUNTIME: "RetentionPolicy" = None def __init__(self, name: str): super().__init__() self._name = name def name(self) -> str: return self._name def toString(self) -> str: return self._name def equals(self, other) -> bool: if isinstance(other, RetentionPolicy): return self._name == other._name return False def hashCode(self) -> int: return hash(self._name) & 0x7FFFFFFF def ordinal(self) -> int: return ["SOURCE", "CLASS", "RUNTIME"].index(self._name) RetentionPolicy.SOURCE = RetentionPolicy("SOURCE") RetentionPolicy.CLASS = RetentionPolicy("CLASS") RetentionPolicy.RUNTIME = RetentionPolicy("RUNTIME") # ============================================================ # ElementType enum # ============================================================ class ElementType(Stub): """ java.lang.annotation.ElementType Enum-like class for annotation target element types. """ TYPE: "ElementType" = None FIELD: "ElementType" = None METHOD: "ElementType" = None PARAMETER: "ElementType" = None CONSTRUCTOR: "ElementType" = None LOCAL_VARIABLE: "ElementType" = None ANNOTATION_TYPE: "ElementType" = None PACKAGE: "ElementType" = None TYPE_PARAMETER: "ElementType" = None TYPE_USE: "ElementType" = None MODULE: "ElementType" = None RECORD_COMPONENT: "ElementType" = None def __init__(self, name: str): super().__init__() self._name = name def name(self) -> str: return self._name def toString(self) -> str: return self._name def equals(self, other) -> bool: if isinstance(other, ElementType): return self._name == other._name return False def hashCode(self) -> int: return hash(self._name) & 0x7FFFFFFF def ordinal(self) -> int: return [ "TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR", "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE", "TYPE_PARAMETER", "TYPE_USE", "MODULE", "RECORD_COMPONENT", ].index(self._name) ElementType.TYPE = ElementType("TYPE") ElementType.FIELD = ElementType("FIELD") ElementType.METHOD = ElementType("METHOD") ElementType.PARAMETER = ElementType("PARAMETER") ElementType.CONSTRUCTOR = ElementType("CONSTRUCTOR") ElementType.LOCAL_VARIABLE = ElementType("LOCAL_VARIABLE") ElementType.ANNOTATION_TYPE = ElementType("ANNOTATION_TYPE") ElementType.PACKAGE = ElementType("PACKAGE") ElementType.TYPE_PARAMETER = ElementType("TYPE_PARAMETER") ElementType.TYPE_USE = ElementType("TYPE_USE") ElementType.MODULE = ElementType("MODULE") ElementType.RECORD_COMPONENT = ElementType("RECORD_COMPONENT") # ============================================================ # Annotation (interface) # ============================================================ class Annotation(Stub): """ java.lang.annotation.Annotation The common interface for all annotation types. """ def __init__(self): super().__init__() def annotationType(self) -> type: """Returns the annotation type of this annotation.""" return self.__class__ def toString(self) -> str: return f"@{self.__class__.__name__}" def equals(self, other) -> bool: return self is other def hashCode(self) -> int: return hash(self.__class__.__name__) & 0x7FFFFFFF # ============================================================ # Documented # ============================================================ class Documented(Annotation): """ java.lang.annotation.Documented Indicates that annotations with a type are to be documented by javadoc. """ def __init__(self): super().__init__() # ============================================================ # Inherited # ============================================================ class Inherited(Annotation): """ java.lang.annotation.Inherited Indicates that an annotation type is automatically inherited. """ def __init__(self): super().__init__() # ============================================================ # Repeatable # ============================================================ class Repeatable(Annotation): """ java.lang.annotation.Repeatable Indicates that the annotation type can be applied more than once. """ def __init__(self, value: type = None): super().__init__() self._value = value def value(self) -> type: return self._value def toString(self) -> str: return f"@Repeatable(value={self._value})" if self._value else "@Repeatable" # ============================================================ # Retention # ============================================================ class Retention(Annotation): """ java.lang.annotation.Retention Indicates how long annotations with the annotated type are to be retained. """ def __init__(self, value: RetentionPolicy = RetentionPolicy.CLASS): super().__init__() self._value = value def value(self) -> RetentionPolicy: return self._value def toString(self) -> str: return f"@Retention(value={self._value})" # ============================================================ # Target # ============================================================ class Target(Annotation): """ java.lang.annotation.Target Indicates the contexts in which an annotation type is applicable. """ def __init__(self, value=None): super().__init__() self._value = value if value is not None else [] def value(self): """Returns the element types this annotation can be applied to.""" return self._value def toString(self) -> str: return f"@Target(value={self._value})" # ============================================================ # Native # ============================================================ class Native(Annotation): """ java.lang.annotation.Native Indicates that a field defining a constant value may be referenced from native code. """ def __init__(self): super().__init__() # ============================================================ # IncompleteAnnotationException # ============================================================ class IncompleteAnnotationException(Exception, Stub): """ java.lang.annotation.IncompleteAnnotationException Thrown when a program attempts to access an annotation with missing elements. """ def __init__(self, annotation_type: type = None, element_name: str = None): super().__init__(f"Annotation {annotation_type} is missing element '{element_name}'") self._annotation_type = annotation_type self._element_name = element_name def annotationType(self) -> type: return self._annotation_type def elementName(self) -> str: return self._element_name def toString(self) -> str: return f"IncompleteAnnotationException: {self._annotation_type} missing '{self._element_name}'" def equals(self, other) -> bool: if not isinstance(other, IncompleteAnnotationException): return False return self._annotation_type == other._annotation_type and self._element_name == other._element_name def hashCode(self) -> int: return hash((str(self._annotation_type), self._element_name)) & 0x7FFFFFFF # ============================================================ # AnnotationFormatError # ============================================================ class AnnotationFormatError(Error, Stub): """ java.lang.annotation.AnnotationFormatError Thrown when the annotation parser attempts to read an annotation from a class file and determines that the annotation is malformed. """ def __init__(self, message: str = None, cause: Exception = None): super().__init__(message, cause) self._message = message def toString(self) -> str: return f"AnnotationFormatError: {self._message}" def equals(self, other) -> bool: if not isinstance(other, AnnotationFormatError): return False return self._message == other._message def hashCode(self) -> int: return hash(self._message) & 0x7FFFFFFF