Skip to main content

lvm_class/attribute/
mod.rs

1//! Attribute types for class files.
2//!
3//! https://docs.oracle.com/javase/specs/jvms/se25/html/jvms-4.html#jvms-4.7
4
5use crate::ClassFormatErr;
6use core::fmt;
7use std::fmt::Formatter;
8
9mod annotation;
10mod class;
11mod field;
12pub mod method;
13mod shared;
14mod type_annotation;
15
16pub use annotation::{Annotation, ElementKind, ElementValue, ElementValuePair};
17pub use class::{BootstrapMethodEntry, ClassAttribute, InnerClassEntry};
18pub use field::FieldAttribute;
19pub use method::{
20    CodeAttribute, ExceptionTableEntry, MethodAttribute, MethodParameterEntry, ParameterAnnotations,
21};
22pub use shared::SharedAttribute;
23pub use type_annotation::{LocalVarEntry, TargetInfo, TypeAnnotation, TypePath, TypePathEntry};
24
25/// Discriminant for attribute types defined in the JVM specification.
26///
27/// https://docs.oracle.com/javase/specs/jvms/se25/html/jvms-4.html#jvms-4.7
28#[derive(Debug, Clone, PartialEq, Eq, Hash)]
29pub enum AttributeKind {
30    ConstantValue,
31    Code,
32    Exceptions,
33    SourceFile,
34    LineNumberTable,
35    LocalVariableTable,
36    InnerClasses,
37    Synthetic,
38    Deprecated,
39    EnclosingMethod,
40    Signature,
41    SourceDebugExtension,
42    LocalVariableTypeTable,
43    RuntimeVisibleAnnotations,
44    RuntimeInvisibleAnnotations,
45    RuntimeVisibleParameterAnnotations,
46    RuntimeInvisibleParameterAnnotations,
47    AnnotationDefault,
48    StackMapTable,
49    BootstrapMethods,
50    RuntimeVisibleTypeAnnotations,
51    RuntimeInvisibleTypeAnnotations,
52    MethodParameters,
53    Module,
54    ModulePackages,
55    ModuleMainClass,
56    NestHost,
57    NestMembers,
58    Record,
59    PermittedSubclasses,
60}
61
62impl AttributeKind {
63    const ATTR_CONSTANT_VALUE: &'static str = "ConstantValue";
64    const ATTR_CODE: &'static str = "Code";
65    const ATTR_EXCEPTIONS: &'static str = "Exceptions";
66    const ATTR_SOURCE_FILE: &'static str = "SourceFile";
67    const ATTR_LINE_NUMBER_TABLE: &'static str = "LineNumberTable";
68    const ATTR_LOCAL_VARIABLE_TABLE: &'static str = "LocalVariableTable";
69    const ATTR_INNER_CLASSES: &'static str = "InnerClasses";
70    const ATTR_SYNTHETIC: &'static str = "Synthetic";
71    const ATTR_DEPRECATED: &'static str = "Deprecated";
72    const ATTR_ENCLOSING_METHOD: &'static str = "EnclosingMethod";
73    const ATTR_SIGNATURE: &'static str = "Signature";
74    const ATTR_SOURCE_DEBUG_EXTENSION: &'static str = "SourceDebugExtension";
75    const ATTR_LOCAL_VARIABLE_TYPE_TABLE: &'static str = "LocalVariableTypeTable";
76    const ATTR_RUNTIME_VISIBLE_ANNOTATIONS: &'static str = "RuntimeVisibleAnnotations";
77    const ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: &'static str = "RuntimeInvisibleAnnotations";
78    const ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: &'static str =
79        "RuntimeVisibleParameterAnnotations";
80    const ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: &'static str =
81        "RuntimeInvisibleParameterAnnotations";
82    const ATTR_ANNOTATION_DEFAULT: &'static str = "AnnotationDefault";
83    const ATTR_STACK_MAP_TABLE: &'static str = "StackMapTable";
84    const ATTR_BOOTSTRAP_METHODS: &'static str = "BootstrapMethods";
85    const ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS: &'static str = "RuntimeVisibleTypeAnnotations";
86    const ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: &'static str = "RuntimeInvisibleTypeAnnotations";
87    const ATTR_METHOD_PARAMETERS: &'static str = "MethodParameters";
88    const ATTR_MODULE: &'static str = "Module";
89    const ATTR_MODULE_PACKAGES: &'static str = "ModulePackages";
90    const ATTR_MODULE_MAIN_CLASS: &'static str = "ModuleMainClass";
91    const ATTR_NEST_HOST: &'static str = "NestHost";
92    const ATTR_NEST_MEMBERS: &'static str = "NestMembers";
93    const ATTR_RECORD: &'static str = "Record";
94    const ATTR_PERMITTED_SUBCLASSES: &'static str = "PermittedSubclasses";
95
96    #[inline]
97    pub const fn as_str(&self) -> &'static str {
98        match self {
99            Self::ConstantValue => Self::ATTR_CONSTANT_VALUE,
100            Self::Code => Self::ATTR_CODE,
101            Self::Exceptions => Self::ATTR_EXCEPTIONS,
102            Self::SourceFile => Self::ATTR_SOURCE_FILE,
103            Self::LineNumberTable => Self::ATTR_LINE_NUMBER_TABLE,
104            Self::LocalVariableTable => Self::ATTR_LOCAL_VARIABLE_TABLE,
105            Self::InnerClasses => Self::ATTR_INNER_CLASSES,
106            Self::Synthetic => Self::ATTR_SYNTHETIC,
107            Self::Deprecated => Self::ATTR_DEPRECATED,
108            Self::EnclosingMethod => Self::ATTR_ENCLOSING_METHOD,
109            Self::Signature => Self::ATTR_SIGNATURE,
110            Self::SourceDebugExtension => Self::ATTR_SOURCE_DEBUG_EXTENSION,
111            Self::LocalVariableTypeTable => Self::ATTR_LOCAL_VARIABLE_TYPE_TABLE,
112            Self::RuntimeVisibleAnnotations => Self::ATTR_RUNTIME_VISIBLE_ANNOTATIONS,
113            Self::RuntimeInvisibleAnnotations => Self::ATTR_RUNTIME_INVISIBLE_ANNOTATIONS,
114            Self::RuntimeVisibleParameterAnnotations => {
115                Self::ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS
116            }
117            Self::RuntimeInvisibleParameterAnnotations => {
118                Self::ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS
119            }
120            Self::AnnotationDefault => Self::ATTR_ANNOTATION_DEFAULT,
121            Self::StackMapTable => Self::ATTR_STACK_MAP_TABLE,
122            Self::BootstrapMethods => Self::ATTR_BOOTSTRAP_METHODS,
123            Self::RuntimeVisibleTypeAnnotations => Self::ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS,
124            Self::RuntimeInvisibleTypeAnnotations => Self::ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS,
125            Self::MethodParameters => Self::ATTR_METHOD_PARAMETERS,
126            Self::Module => Self::ATTR_MODULE,
127            Self::ModulePackages => Self::ATTR_MODULE_PACKAGES,
128            Self::ModuleMainClass => Self::ATTR_MODULE_MAIN_CLASS,
129            Self::NestHost => Self::ATTR_NEST_HOST,
130            Self::NestMembers => Self::ATTR_NEST_MEMBERS,
131            Self::Record => Self::ATTR_RECORD,
132            Self::PermittedSubclasses => Self::ATTR_PERMITTED_SUBCLASSES,
133        }
134    }
135}
136
137impl TryFrom<&str> for AttributeKind {
138    type Error = ClassFormatErr;
139
140    fn try_from(s: &str) -> Result<Self, Self::Error> {
141        Ok(match s {
142            Self::ATTR_CONSTANT_VALUE => Self::ConstantValue,
143            Self::ATTR_CODE => Self::Code,
144            Self::ATTR_EXCEPTIONS => Self::Exceptions,
145            Self::ATTR_SOURCE_FILE => Self::SourceFile,
146            Self::ATTR_LINE_NUMBER_TABLE => Self::LineNumberTable,
147            Self::ATTR_LOCAL_VARIABLE_TABLE => Self::LocalVariableTable,
148            Self::ATTR_INNER_CLASSES => Self::InnerClasses,
149            Self::ATTR_SYNTHETIC => Self::Synthetic,
150            Self::ATTR_DEPRECATED => Self::Deprecated,
151            Self::ATTR_ENCLOSING_METHOD => Self::EnclosingMethod,
152            Self::ATTR_SIGNATURE => Self::Signature,
153            Self::ATTR_SOURCE_DEBUG_EXTENSION => Self::SourceDebugExtension,
154            Self::ATTR_LOCAL_VARIABLE_TYPE_TABLE => Self::LocalVariableTypeTable,
155            Self::ATTR_RUNTIME_VISIBLE_ANNOTATIONS => Self::RuntimeVisibleAnnotations,
156            Self::ATTR_RUNTIME_INVISIBLE_ANNOTATIONS => Self::RuntimeInvisibleAnnotations,
157            Self::ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS => {
158                Self::RuntimeVisibleParameterAnnotations
159            }
160            Self::ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS => {
161                Self::RuntimeInvisibleParameterAnnotations
162            }
163            Self::ATTR_ANNOTATION_DEFAULT => Self::AnnotationDefault,
164            Self::ATTR_STACK_MAP_TABLE => Self::StackMapTable,
165            Self::ATTR_BOOTSTRAP_METHODS => Self::BootstrapMethods,
166            Self::ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS => Self::RuntimeVisibleTypeAnnotations,
167            Self::ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS => Self::RuntimeInvisibleTypeAnnotations,
168            Self::ATTR_METHOD_PARAMETERS => Self::MethodParameters,
169            Self::ATTR_MODULE => Self::Module,
170            Self::ATTR_MODULE_PACKAGES => Self::ModulePackages,
171            Self::ATTR_MODULE_MAIN_CLASS => Self::ModuleMainClass,
172            Self::ATTR_NEST_HOST => Self::NestHost,
173            Self::ATTR_NEST_MEMBERS => Self::NestMembers,
174            Self::ATTR_RECORD => Self::Record,
175            Self::ATTR_PERMITTED_SUBCLASSES => Self::PermittedSubclasses,
176            _ => return Err(ClassFormatErr::UnknownAttribute(s.to_string())),
177        })
178    }
179}
180
181impl fmt::Display for AttributeKind {
182    #[inline]
183    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
184        f.write_str(self.as_str())
185    }
186}