put pyo3 away for now
This commit is contained in:
parent
ea6ce5d7a1
commit
1c45b9e38b
15 changed files with 248 additions and 215 deletions
|
|
@ -14,8 +14,8 @@ androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serialize
|
||||||
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
||||||
apk_frauder = { version = "0.1.0", path = "../apk_frauder" }
|
apk_frauder = { version = "0.1.0", path = "../apk_frauder" }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
pyo3 = { version = "0.23.4", features = ["anyhow", "abi3-py38"] }
|
pyo3 = { version = "0.23.4", features = ["anyhow", "abi3-py38", "extension-module"], optional = true}
|
||||||
pyo3-log = "0.12.1"
|
pyo3-log = { version = "0.12.1", optional = true}
|
||||||
rayon = "1.9.0"
|
rayon = "1.9.0"
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
|
|
@ -24,6 +24,7 @@ sha1 = "0.10.6"
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.4.1"
|
pretty_assertions = "1.4.1"
|
||||||
|
|
||||||
#[features]
|
[features]
|
||||||
#extension-module = ["pyo3/extension-module"]
|
default = []
|
||||||
#default = [""]
|
# TODO: need refactoring to https://github.com/PyO3/pyo3/issues/2935#issuecomment-2560930677 or cfg_eval https://github.com/rust-lang/rust/issues/82679
|
||||||
|
python = ["pyo3", "pyo3-log"]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::hashmap_vectorize;
|
use crate::hashmap_vectorize;
|
||||||
|
|
@ -11,28 +12,28 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Annotation with a visibility
|
/// Annotation with a visibility
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct DexAnnotationItem {
|
pub struct DexAnnotationItem {
|
||||||
// TODO: the get/set will probably be wonky on the python side when edditing
|
// TODO: the get/set will probably be wonky on the python side when edditing
|
||||||
/// The actual annotation
|
/// The actual annotation
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub annotation: DexAnnotation,
|
pub annotation: DexAnnotation,
|
||||||
// TODO: enforce exclusivity
|
// TODO: enforce exclusivity
|
||||||
/// If the annotation visibility is set to build
|
/// If the annotation visibility is set to build
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub visibility_build: bool,
|
pub visibility_build: bool,
|
||||||
/// If the annotation visibility is set to runtime
|
/// If the annotation visibility is set to runtime
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub visibility_runtime: bool,
|
pub visibility_runtime: bool,
|
||||||
/// If the annotation visibility is set to system
|
/// If the annotation visibility is set to system
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub visibility_system: bool,
|
pub visibility_system: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexAnnotationItem {
|
impl DexAnnotationItem {
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(annotation: DexAnnotation) -> Self {
|
pub fn new(annotation: DexAnnotation) -> Self {
|
||||||
Self {
|
Self {
|
||||||
annotation,
|
annotation,
|
||||||
|
|
@ -101,7 +102,7 @@ impl DexAnnotationItem {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
@ -122,23 +123,23 @@ impl<V: VisitorMut> VisitableMut<V> for DexAnnotationItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An annotation.
|
/// An annotation.
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct DexAnnotation {
|
pub struct DexAnnotation {
|
||||||
// TODO: check the relation between type and encoded_value.
|
// TODO: check the relation between type and encoded_value.
|
||||||
/// The type of the annotation.
|
/// The type of the annotation.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub type_: IdType,
|
pub type_: IdType,
|
||||||
// TODO: the get/set will probably be wonky on the python side when edditing
|
// TODO: the get/set will probably be wonky on the python side when edditing
|
||||||
/// The annotation elements.
|
/// The annotation elements.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
#[serde(with = "hashmap_vectorize")]
|
#[serde(with = "hashmap_vectorize")]
|
||||||
pub elements: HashMap<DexString, DexValue>, // TODO: check MemberName syntax?
|
pub elements: HashMap<DexString, DexValue>, // TODO: check MemberName syntax?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexAnnotation {
|
impl DexAnnotation {
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(type_: IdType, elements: HashMap<DexString, DexValue>) -> Self {
|
pub fn new(type_: IdType, elements: HashMap<DexString, DexValue>) -> Self {
|
||||||
Self { type_, elements }
|
Self { type_, elements }
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +219,7 @@ impl DexAnnotation {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use std::io::Cursor;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use pyo3::prelude::*;
|
#[cfg(feature = "python")]
|
||||||
use pyo3::types::PyBytes;
|
use pyo3::{prelude::*, types::PyBytes};
|
||||||
|
|
||||||
use crate::ins::CallSite;
|
use crate::ins::CallSite;
|
||||||
use crate::instructions;
|
use crate::instructions;
|
||||||
|
|
@ -32,7 +32,7 @@ pub struct DexFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represent an apk.
|
/// Represent an apk.
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
|
||||||
pub struct Apk {
|
pub struct Apk {
|
||||||
pub dex_files: HashMap<String, DexFile>, // TODO: use accessort for chache invalidation
|
pub dex_files: HashMap<String, DexFile>, // TODO: use accessort for chache invalidation
|
||||||
|
|
@ -2981,9 +2981,9 @@ impl Apk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl Apk {
|
impl Apk {
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
// TODO take argument and dispatch to load_apk or load_apk_bin
|
// TODO take argument and dispatch to load_apk or load_apk_bin
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -2993,8 +2993,8 @@ impl Apk {
|
||||||
|
|
||||||
/// Load all android files in an application.
|
/// Load all android files in an application.
|
||||||
/// This **does not include any .dex file that android would not load.
|
/// This **does not include any .dex file that android would not load.
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
#[pyo3(signature = (apk, label_each_ins=false, cache=false))]
|
#[cfg_attr(feature = "python", pyo3(signature = (apk, label_each_ins=false, cache=false)))]
|
||||||
pub fn load_apk(apk: PathBuf, label_each_ins: bool, cache: bool) -> Result<Self> {
|
pub fn load_apk(apk: PathBuf, label_each_ins: bool, cache: bool) -> Result<Self> {
|
||||||
let file = File::open(apk)?;
|
let file = File::open(apk)?;
|
||||||
let mut apk_z = ZipFileReader::new(file);
|
let mut apk_z = ZipFileReader::new(file);
|
||||||
|
|
@ -3013,8 +3013,8 @@ impl Apk {
|
||||||
|
|
||||||
/// Load all android files in an application.
|
/// Load all android files in an application.
|
||||||
/// This **does not include any .dex file that android would not load.
|
/// This **does not include any .dex file that android would not load.
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
#[pyo3(signature = (apk, label_each_ins=false, cache=false))]
|
#[cfg_attr(feature = "python", pyo3(signature = (apk, label_each_ins=false, cache=false)))]
|
||||||
pub fn load_apk_bin(apk: &[u8], label_each_ins: bool, cache: bool) -> Result<Self> {
|
pub fn load_apk_bin(apk: &[u8], label_each_ins: bool, cache: bool) -> Result<Self> {
|
||||||
let mut apk_z = ZipFileReader::new(Cursor::new(apk));
|
let mut apk_z = ZipFileReader::new(Cursor::new(apk));
|
||||||
let mut apk = Self::default();
|
let mut apk = Self::default();
|
||||||
|
|
@ -3039,7 +3039,7 @@ impl Apk {
|
||||||
/// - `label_each_ins`: if set to true, insert a label before each instruction
|
/// - `label_each_ins`: if set to true, insert a label before each instruction
|
||||||
/// indicating the instruction address
|
/// indicating the instruction address
|
||||||
/// - `cache`: if set to true, copy and cache the binary data format.
|
/// - `cache`: if set to true, copy and cache the binary data format.
|
||||||
#[pyo3(signature = (name, data, label_each_ins=false, cache=false))]
|
#[cfg_attr(feature = "python", pyo3(signature = (name, data, label_each_ins=false, cache=false)))]
|
||||||
pub fn add_dex_file(
|
pub fn add_dex_file(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
|
@ -3096,7 +3096,7 @@ impl Apk {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(signature = (method_id, code=None, dex_file=None))]
|
#[cfg_attr(feature = "python", pyo3(signature = (method_id, code=None, dex_file=None)))]
|
||||||
pub fn set_method_code(
|
pub fn set_method_code(
|
||||||
&mut self,
|
&mut self,
|
||||||
method_id: IdMethod,
|
method_id: IdMethod,
|
||||||
|
|
@ -3131,6 +3131,7 @@ impl Apk {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
#[pyo3(name = "gen_raw_dex")] //Sad GIL noise
|
#[pyo3(name = "gen_raw_dex")] //Sad GIL noise
|
||||||
pub fn py_gen_raw_dex(&self, py: Python<'_>) -> Result<HashMap<String, PyObject>> {
|
pub fn py_gen_raw_dex(&self, py: Python<'_>) -> Result<HashMap<String, PyObject>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
|
|
@ -3144,12 +3145,12 @@ impl Apk {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(signature = (class, dex_file=None))]
|
#[cfg_attr(feature = "python", pyo3(signature = (class, dex_file=None)))]
|
||||||
pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> {
|
pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> {
|
||||||
if let Some(dex_file) = dex_file {
|
if let Some(dex_file) = dex_file {
|
||||||
self.dex_files
|
self.dex_files
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -12,80 +13,80 @@ use crate::{
|
||||||
use androscalpel_serializer::consts::*;
|
use androscalpel_serializer::consts::*;
|
||||||
|
|
||||||
/// Represent an apk
|
/// Represent an apk
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct Class {
|
pub struct Class {
|
||||||
/// Type, format described at
|
/// Type, format described at
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub descriptor: IdType,
|
pub descriptor: IdType,
|
||||||
/// If the class is visible everywhere
|
/// If the class is visible everywhere
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_public: bool,
|
pub is_public: bool,
|
||||||
/// If the class is subclassable
|
/// If the class is subclassable
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_final: bool,
|
pub is_final: bool,
|
||||||
/// If the class is a 'multipy-implementable abstract class' AKA an interface
|
/// If the class is a 'multipy-implementable abstract class' AKA an interface
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_interface: bool,
|
pub is_interface: bool,
|
||||||
/// If the class is instanciable
|
/// If the class is instanciable
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_abstract: bool,
|
pub is_abstract: bool,
|
||||||
/// If the class is not directly defined in the source code
|
/// If the class is not directly defined in the source code
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_synthetic: bool,
|
pub is_synthetic: bool,
|
||||||
/// If the class is an annotation
|
/// If the class is an annotation
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_annotation: bool,
|
pub is_annotation: bool,
|
||||||
/// If the class is an enum
|
/// If the class is an enum
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_enum: bool,
|
pub is_enum: bool,
|
||||||
/// Name of the superclass, format described at
|
/// Name of the superclass, format described at
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub superclass: Option<IdType>,
|
pub superclass: Option<IdType>,
|
||||||
/// List of the interfaces that class implement, format of the interfaces
|
/// List of the interfaces that class implement, format of the interfaces
|
||||||
/// name is discribed at
|
/// name is discribed at
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
/// <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub interfaces: Vec<IdType>,
|
pub interfaces: Vec<IdType>,
|
||||||
/// Name of the source file where this class is defined.
|
/// Name of the source file where this class is defined.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub source_file: Option<DexString>,
|
pub source_file: Option<DexString>,
|
||||||
|
|
||||||
/// The static fields
|
/// The static fields
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub static_fields: HashMap<IdField, Field>,
|
pub static_fields: HashMap<IdField, Field>,
|
||||||
/// The instance fields
|
/// The instance fields
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub instance_fields: HashMap<IdField, Field>,
|
pub instance_fields: HashMap<IdField, Field>,
|
||||||
/// The direct (static, private or constructor) methods of the class
|
/// The direct (static, private or constructor) methods of the class
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub direct_methods: HashMap<IdMethod, Method>,
|
pub direct_methods: HashMap<IdMethod, Method>,
|
||||||
/// The virtual (ie non direct) methods of the class
|
/// The virtual (ie non direct) methods of the class
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub virtual_methods: HashMap<IdMethod, Method>,
|
pub virtual_methods: HashMap<IdMethod, Method>,
|
||||||
// Do we need to distinguish direct and virtual (all the other) methods?
|
// Do we need to distinguish direct and virtual (all the other) methods?
|
||||||
// Maybe overlapping descriptor (same name, class and proto?)
|
// Maybe overlapping descriptor (same name, class and proto?)
|
||||||
/// The annotation related to this class (note: this does not include the
|
/// The annotation related to this class (note: this does not include the
|
||||||
/// methods/field/parameters annotations, they are stored in the methods and fields
|
/// methods/field/parameters annotations, they are stored in the methods and fields
|
||||||
/// structutres)
|
/// structutres)
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub annotations: Vec<DexAnnotationItem>,
|
pub annotations: Vec<DexAnnotationItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl Class {
|
impl Class {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(name: DexString) -> Result<Self> {
|
pub fn new(name: DexString) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
descriptor: IdType::new(name)?,
|
descriptor: IdType::new(name)?,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use anyhow::anyhow;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -16,26 +17,26 @@ use crate::{
|
||||||
// type TmpHandlerType = (Vec<(IdType, u32)>, Option<u32>);
|
// type TmpHandlerType = (Vec<(IdType, u32)>, Option<u32>);
|
||||||
|
|
||||||
/// The code run by a method.
|
/// The code run by a method.
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct Code {
|
pub struct Code {
|
||||||
// TODO: remove and compute this value from code?
|
// TODO: remove and compute this value from code?
|
||||||
/// The number of registers used by the code
|
/// The number of registers used by the code
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub registers_size: u16,
|
pub registers_size: u16,
|
||||||
// TODO: what does it means? is it computable?
|
// TODO: what does it means? is it computable?
|
||||||
/// The number of words of incoming arguments to the method
|
/// The number of words of incoming arguments to the method
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub ins_size: u16,
|
pub ins_size: u16,
|
||||||
// TODO: what does it means? is it computable?
|
// TODO: what does it means? is it computable?
|
||||||
/// The number of words of outgoing argument space
|
/// The number of words of outgoing argument space
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub outs_size: u16,
|
pub outs_size: u16,
|
||||||
/// The names of the parameters if given
|
/// The names of the parameters if given
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub parameter_names: Option<Vec<Option<DexString>>>,
|
pub parameter_names: Option<Vec<Option<DexString>>>,
|
||||||
/// The instructions.
|
/// The instructions.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub insns: Vec<Instruction>,
|
pub insns: Vec<Instruction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,19 +52,19 @@ impl PartialEq for Code {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl Code {
|
impl Code {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
#[pyo3(signature = (registers_size, ins_size, outs_size, insns, parameter_names=None))]
|
#[cfg_attr(feature = "python", pyo3(signature = (registers_size, ins_size, outs_size, insns, parameter_names=None)))]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
registers_size: u16,
|
registers_size: u16,
|
||||||
ins_size: u16,
|
ins_size: u16,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use std::collections::HashSet;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Context};
|
use anyhow::{anyhow, bail, Context};
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{scalar::*, DexString, DexValue, Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
use crate::{scalar::*, DexString, DexValue, Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
||||||
|
|
@ -13,7 +14,7 @@ use androscalpel_serializer::{StringDataItem, Uleb128};
|
||||||
|
|
||||||
/// The type of a method. The shorty is formated as described in
|
/// The type of a method. The shorty is formated as described in
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||||
#[pyclass(eq, ord, hash, frozen)]
|
#[cfg_attr(feature = "python", pyclass(eq, ord, hash, frozen))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct IdMethodType {
|
pub struct IdMethodType {
|
||||||
/// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
/// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||||
|
|
@ -62,18 +63,18 @@ impl PartialOrd for IdMethodType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl IdMethodType {
|
impl IdMethodType {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(return_type: IdType, parameters: Vec<IdType>) -> Self {
|
pub fn new(return_type: IdType, parameters: Vec<IdType>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
shorty: Self::compute_shorty(&return_type, ¶meters),
|
shorty: Self::compute_shorty(&return_type, ¶meters),
|
||||||
|
|
@ -100,7 +101,7 @@ impl IdMethodType {
|
||||||
/// )
|
/// )
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
||||||
if smali_repr.len() < 2 {
|
if smali_repr.len() < 2 {
|
||||||
bail!("'{smali_repr}' is to short to be a prototype");
|
bail!("'{smali_repr}' is to short to be a prototype");
|
||||||
|
|
@ -229,7 +230,7 @@ impl IdMethodType {
|
||||||
/// as described here <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
/// as described here <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||||
// Not a clean rust enum because we want to be compatible with python, and maybe support strange
|
// Not a clean rust enum because we want to be compatible with python, and maybe support strange
|
||||||
// malware edge case?
|
// malware edge case?
|
||||||
#[pyclass(eq, ord, hash, frozen)]
|
#[cfg_attr(feature = "python", pyclass(eq, ord, hash, frozen))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct IdType(pub(crate) DexString);
|
pub struct IdType(pub(crate) DexString);
|
||||||
|
|
||||||
|
|
@ -244,20 +245,24 @@ impl<V: VisitorMut> VisitableMut<V> for IdType {
|
||||||
Ok(Self(v.visit_string(self.0)?))
|
Ok(Self(v.visit_string(self.0)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl IdType {
|
impl IdType {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
#[pyo3(from_py_with = "crate::dex_string::as_dex_string")] ty: DexString,
|
#[cfg_attr(
|
||||||
|
feature = "python",
|
||||||
|
pyo3(from_py_with = "crate::dex_string::as_dex_string")
|
||||||
|
)]
|
||||||
|
ty: DexString,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// TODO: check format
|
// TODO: check format
|
||||||
let ty = Self(ty);
|
let ty = Self(ty);
|
||||||
|
|
@ -266,7 +271,7 @@ impl IdType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a type from its string representation without checking its format
|
/// Return a type from its string representation without checking its format
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn unchecked_new(ty: DexString) -> Self {
|
pub fn unchecked_new(ty: DexString) -> Self {
|
||||||
Self(ty)
|
Self(ty)
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +293,7 @@ impl IdType {
|
||||||
/// IdType::class("androidx/core/util/Predicate")
|
/// IdType::class("androidx/core/util/Predicate")
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
||||||
Self::new(smali_repr.into())
|
Self::new(smali_repr.into())
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +315,7 @@ impl IdType {
|
||||||
/// IdType::boolean(),
|
/// IdType::boolean(),
|
||||||
/// ])
|
/// ])
|
||||||
/// ```
|
/// ```
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn get_list_from_str(type_list: &str) -> Result<Vec<Self>> {
|
pub fn get_list_from_str(type_list: &str) -> Result<Vec<Self>> {
|
||||||
let mut lst = vec![];
|
let mut lst = vec![];
|
||||||
let mut chars = type_list.chars();
|
let mut chars = type_list.chars();
|
||||||
|
|
@ -364,66 +369,66 @@ impl IdType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the void type (for return type)
|
/// Return the void type (for return type)
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn void() -> Self {
|
pub fn void() -> Self {
|
||||||
Self("V".into())
|
Self("V".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the boolean type
|
/// Return the boolean type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn boolean() -> Self {
|
pub fn boolean() -> Self {
|
||||||
Self("Z".into())
|
Self("Z".into())
|
||||||
}
|
}
|
||||||
/// Return the byte type
|
/// Return the byte type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn byte() -> Self {
|
pub fn byte() -> Self {
|
||||||
Self("B".into())
|
Self("B".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the short type
|
/// Return the short type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn short() -> Self {
|
pub fn short() -> Self {
|
||||||
Self("S".into())
|
Self("S".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the char type
|
/// Return the char type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn char() -> Self {
|
pub fn char() -> Self {
|
||||||
Self("C".into())
|
Self("C".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the int type
|
/// Return the int type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn int() -> Self {
|
pub fn int() -> Self {
|
||||||
Self("I".into())
|
Self("I".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the long type
|
/// Return the long type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn long() -> Self {
|
pub fn long() -> Self {
|
||||||
Self("J".into())
|
Self("J".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the float type
|
/// Return the float type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn float() -> Self {
|
pub fn float() -> Self {
|
||||||
Self("F".into())
|
Self("F".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the double type
|
/// Return the double type
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn double() -> Self {
|
pub fn double() -> Self {
|
||||||
Self("D".into())
|
Self("D".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the type for the class of fully qualified name `name`
|
/// Return the type for the class of fully qualified name `name`
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn class(name: &str) -> Self {
|
pub fn class(name: &str) -> Self {
|
||||||
Self(format!("L{name};").into())
|
Self(format!("L{name};").into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the type for an array of the specify `type_`
|
/// Return the type for an array of the specify `type_`
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn array(type_: &IdType) -> Self {
|
pub fn array(type_: &IdType) -> Self {
|
||||||
let mut ty = type_.clone();
|
let mut ty = type_.clone();
|
||||||
ty.0 .0.utf16_size.0 += 1;
|
ty.0 .0.utf16_size.0 += 1;
|
||||||
|
|
@ -636,18 +641,18 @@ impl SmaliName for IdType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq, ord, hash, frozen)]
|
#[cfg_attr(feature = "python", pyclass(eq, ord, hash, frozen))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct IdField {
|
pub struct IdField {
|
||||||
/// The name of the field, format described at
|
/// The name of the field, format described at
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#membername>
|
/// <https://source.android.com/docs/core/runtime/dex-format#membername>
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub name: DexString,
|
pub name: DexString,
|
||||||
/// The type of the field.
|
/// The type of the field.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub type_: IdType,
|
pub type_: IdType,
|
||||||
/// The class that own the field.
|
/// The class that own the field.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub class_: IdType,
|
pub class_: IdType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -669,20 +674,24 @@ impl<V: VisitorMut> VisitableMut<V> for IdField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl IdField {
|
impl IdField {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
#[pyo3(from_py_with = "crate::dex_string::as_dex_string")] name: DexString,
|
#[cfg_attr(
|
||||||
|
feature = "python",
|
||||||
|
pyo3(from_py_with = "crate::dex_string::as_dex_string")
|
||||||
|
)]
|
||||||
|
name: DexString,
|
||||||
type_: IdType,
|
type_: IdType,
|
||||||
class_: IdType,
|
class_: IdType,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -709,7 +718,7 @@ impl IdField {
|
||||||
/// )
|
/// )
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
||||||
let arrow_i = smali_repr.find("->");
|
let arrow_i = smali_repr.find("->");
|
||||||
if arrow_i.is_none() {
|
if arrow_i.is_none() {
|
||||||
|
|
@ -803,17 +812,17 @@ impl SmaliName for IdField {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Id of a method.
|
/// The Id of a method.
|
||||||
#[pyclass(eq, ord, hash, frozen)]
|
#[cfg_attr(feature = "python", pyclass(eq, ord, hash, frozen))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct IdMethod {
|
pub struct IdMethod {
|
||||||
/// The class containing the method.
|
/// The class containing the method.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub class_: IdType,
|
pub class_: IdType,
|
||||||
/// The prototype (aka type or signature) of the method.
|
/// The prototype (aka type or signature) of the method.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub proto: IdMethodType,
|
pub proto: IdMethodType,
|
||||||
/// The name of the method.
|
/// The name of the method.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub name: DexString,
|
pub name: DexString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -835,20 +844,24 @@ impl<V: VisitorMut> VisitableMut<V> for IdMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl IdMethod {
|
impl IdMethod {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
#[pyo3(from_py_with = "crate::dex_string::as_dex_string")] name: DexString,
|
#[cfg_attr(
|
||||||
|
feature = "python",
|
||||||
|
pyo3(from_py_with = "crate::dex_string::as_dex_string")
|
||||||
|
)]
|
||||||
|
name: DexString,
|
||||||
proto: IdMethodType,
|
proto: IdMethodType,
|
||||||
class_: IdType,
|
class_: IdType,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -884,7 +897,7 @@ impl IdMethod {
|
||||||
/// )
|
/// )
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
pub fn from_smali(smali_repr: &str) -> Result<Self> {
|
||||||
let arrow_i = smali_repr.find("->");
|
let arrow_i = smali_repr.find("->");
|
||||||
if arrow_i.is_none() {
|
if arrow_i.is_none() {
|
||||||
|
|
@ -998,7 +1011,7 @@ impl SmaliName for IdMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq, ord, hash, frozen)]
|
#[cfg_attr(feature = "python", pyclass(eq, ord, hash, frozen))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||||
pub struct IdEnum(pub IdField);
|
pub struct IdEnum(pub IdField);
|
||||||
|
|
||||||
|
|
@ -1014,18 +1027,18 @@ impl<V: VisitorMut> VisitableMut<V> for IdEnum {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl IdEnum {
|
impl IdEnum {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: IdField) -> Self {
|
pub fn new(val: IdField) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
||||||
use pyo3::exceptions::PyTypeError;
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::cmp::{Ord, PartialOrd};
|
use std::cmp::{Ord, PartialOrd};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
#[cfg(feature = "python")]
|
||||||
|
use pyo3::{exceptions::PyTypeError, prelude::*};
|
||||||
|
|
||||||
#[pyclass(eq, ord, frozen, hash)]
|
#[cfg_attr(feature = "python", pyclass(eq, ord, frozen, hash))]
|
||||||
#[derive(Clone, PartialEq, Eq, Ord, PartialOrd)]
|
#[derive(Clone, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
pub struct DexString(pub androscalpel_serializer::StringDataItem);
|
pub struct DexString(pub androscalpel_serializer::StringDataItem);
|
||||||
|
|
||||||
|
|
@ -149,6 +149,7 @@ impl Hash for DexString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
pub fn as_dex_string(obj: &Bound<'_, PyAny>) -> PyResult<DexString> {
|
pub fn as_dex_string(obj: &Bound<'_, PyAny>) -> PyResult<DexString> {
|
||||||
if let Ok(string) = DexString::extract_bound(obj) {
|
if let Ok(string) = DexString::extract_bound(obj) {
|
||||||
Ok(string)
|
Ok(string)
|
||||||
|
|
@ -162,18 +163,18 @@ pub fn as_dex_string(obj: &Bound<'_, PyAny>) -> PyResult<DexString> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexString {
|
impl DexString {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(s: &str) -> Self {
|
pub fn new(s: &str) -> Self {
|
||||||
s.into()
|
s.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -12,45 +13,45 @@ use crate::{
|
||||||
use androscalpel_serializer::consts::*;
|
use androscalpel_serializer::consts::*;
|
||||||
|
|
||||||
/// Represent a field.
|
/// Represent a field.
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
/// The structure used to reference this field.
|
/// The structure used to reference this field.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub descriptor: IdField,
|
pub descriptor: IdField,
|
||||||
/// The field visibility
|
/// The field visibility
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub visibility: FieldVisibility,
|
pub visibility: FieldVisibility,
|
||||||
/// If the field is defined for the class globally
|
/// If the field is defined for the class globally
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_static: bool,
|
pub is_static: bool,
|
||||||
/// If the field is immutable after construction
|
/// If the field is immutable after construction
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_final: bool,
|
pub is_final: bool,
|
||||||
/// For thread safety
|
/// For thread safety
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_volatile: bool,
|
pub is_volatile: bool,
|
||||||
/// If the field should **not** be saved by default serialization
|
/// If the field should **not** be saved by default serialization
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_transient: bool,
|
pub is_transient: bool,
|
||||||
/// If the field is not defined in the source code
|
/// If the field is not defined in the source code
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_synthetic: bool,
|
pub is_synthetic: bool,
|
||||||
/// If the field is an enumerated value
|
/// If the field is an enumerated value
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_enum: bool,
|
pub is_enum: bool,
|
||||||
/// The default value of this field
|
/// The default value of this field
|
||||||
pub value: Option<DexValue>,
|
pub value: Option<DexValue>,
|
||||||
/// The annotations for this field
|
/// The annotations for this field
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub annotations: Vec<DexAnnotationItem>,
|
pub annotations: Vec<DexAnnotationItem>,
|
||||||
/// Hidden Api data.
|
/// Hidden Api data.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub hiddenapi: Option<HiddenApiData>,
|
pub hiddenapi: Option<HiddenApiData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represent the visibility of a field
|
/// Represent the visibility of a field
|
||||||
#[pyclass(eq, eq_int)]
|
#[cfg_attr(feature = "python", pyclass(eq, eq_int))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub enum FieldVisibility {
|
pub enum FieldVisibility {
|
||||||
Public,
|
Public,
|
||||||
|
|
@ -59,18 +60,18 @@ pub enum FieldVisibility {
|
||||||
None_, // Actually quite common
|
None_, // Actually quite common
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl Field {
|
impl Field {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(descriptor: IdField) -> Self {
|
pub fn new(descriptor: IdField) -> Self {
|
||||||
Self {
|
Self {
|
||||||
descriptor,
|
descriptor,
|
||||||
|
|
@ -124,12 +125,14 @@ impl Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value as a python object
|
/// Return the value as a python object
|
||||||
|
#[cfg(feature = "python")]
|
||||||
#[getter]
|
#[getter]
|
||||||
pub fn get_value(&self) -> Option<DexValue> {
|
pub fn get_value(&self) -> Option<DexValue> {
|
||||||
self.value.clone()
|
self.value.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the value from a python object
|
/// Set the value from a python object
|
||||||
|
#[cfg(feature = "python")]
|
||||||
#[setter]
|
#[setter]
|
||||||
pub fn set_value(&mut self, ob: &Bound<'_, PyAny>) -> PyResult<()> {
|
pub fn set_value(&mut self, ob: &Bound<'_, PyAny>) -> PyResult<()> {
|
||||||
self.value = Some(ob.extract()?);
|
self.value = Some(ob.extract()?);
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
use crate::{Result, Visitable, VisitableMut, Visitor, VisitorMut};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[pyclass]
|
#[cfg_attr(feature = "python", pyclass)]
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
||||||
pub struct HiddenApiData {
|
pub struct HiddenApiData {
|
||||||
pub permission: HiddenApiPermission,
|
pub permission: HiddenApiPermission,
|
||||||
|
|
@ -56,7 +57,7 @@ impl<V: VisitorMut> VisitableMut<V> for HiddenApiData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass]
|
#[cfg_attr(feature = "python", pyclass)]
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
||||||
pub enum HiddenApiPermission {
|
pub enum HiddenApiPermission {
|
||||||
/// Interfaces that can be freely used and are supported as
|
/// Interfaces that can be freely used and are supported as
|
||||||
|
|
@ -147,7 +148,7 @@ impl From<HiddenApiPermission> for androscalpel_serializer::HiddenApiValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass]
|
#[cfg_attr(feature = "python", pyclass)]
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
|
||||||
pub struct HiddenApiDomain {
|
pub struct HiddenApiDomain {
|
||||||
pub is_core_platform_api: bool,
|
pub is_core_platform_api: bool,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use androscalpel_serializer::Instruction as InsFormat;
|
||||||
use androscalpel_serializer::Serializable;
|
use androscalpel_serializer::Serializable;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail};
|
use anyhow::{anyhow, bail};
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
@ -31,7 +32,7 @@ const I32_MIN_AS_I64: i64 = i32::MIN as i64;
|
||||||
const I32_MAX_AS_I64: i64 = i32::MAX as i64;
|
const I32_MAX_AS_I64: i64 = i32::MAX as i64;
|
||||||
const U16_MAX_AS_USIZE: usize = u16::MAX as usize;
|
const U16_MAX_AS_USIZE: usize = u16::MAX as usize;
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub enum Instruction {
|
pub enum Instruction {
|
||||||
/// Waste a cycle.
|
/// Waste a cycle.
|
||||||
|
|
@ -2094,13 +2095,13 @@ macro_rules! raw_ins_invoke {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl Instruction {
|
impl Instruction {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
@ -6596,31 +6597,31 @@ impl Instruction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct CallSite {
|
pub struct CallSite {
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub method_handle: MethodHandle,
|
pub method_handle: MethodHandle,
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub name: DexString,
|
pub name: DexString,
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub type_: IdMethodType,
|
pub type_: IdMethodType,
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub args: Vec<DexValue>,
|
pub args: Vec<DexValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl CallSite {
|
impl CallSite {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
method_handle: MethodHandle,
|
method_handle: MethodHandle,
|
||||||
name: DexString,
|
name: DexString,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// python, TryInto should be prefered
|
// python, TryInto should be prefered
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
pub mod annotation;
|
pub mod annotation;
|
||||||
|
|
@ -18,6 +19,7 @@ pub mod hiddenapi;
|
||||||
pub mod instructions;
|
pub mod instructions;
|
||||||
pub mod method;
|
pub mod method;
|
||||||
pub mod method_handle;
|
pub mod method_handle;
|
||||||
|
#[cfg(feature = "python")]
|
||||||
pub mod py_utils;
|
pub mod py_utils;
|
||||||
pub mod scalar;
|
pub mod scalar;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
@ -44,6 +46,7 @@ pub use visitor::*;
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
/// Androscalpel.
|
/// Androscalpel.
|
||||||
|
#[cfg(feature = "python")]
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn androscalpel(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
fn androscalpel(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||||
pyo3_log::init();
|
pyo3_log::init();
|
||||||
|
|
@ -90,6 +93,7 @@ fn androscalpel(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dalvik opcode for Androscalpel.
|
/// Dalvik opcode for Androscalpel.
|
||||||
|
#[cfg(feature = "python")]
|
||||||
fn androscalpel_ins(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
fn androscalpel_ins(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||||
m.add_class::<ins::CallSite>()?;
|
m.add_class::<ins::CallSite>()?;
|
||||||
m.add_class::<ins::Instruction>()?;
|
m.add_class::<ins::Instruction>()?;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -12,67 +13,67 @@ use crate::{
|
||||||
use androscalpel_serializer::consts::*;
|
use androscalpel_serializer::consts::*;
|
||||||
|
|
||||||
/// Represent a method.
|
/// Represent a method.
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct Method {
|
pub struct Method {
|
||||||
/// The structure used to reference this method.
|
/// The structure used to reference this method.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub descriptor: IdMethod,
|
pub descriptor: IdMethod,
|
||||||
/// The field visibility.
|
/// The field visibility.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub visibility: MethodVisibility,
|
pub visibility: MethodVisibility,
|
||||||
/// Static methods do not take this in argument.
|
/// Static methods do not take this in argument.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_static: bool,
|
pub is_static: bool,
|
||||||
/// Final methods are not averridable.
|
/// Final methods are not averridable.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_final: bool,
|
pub is_final: bool,
|
||||||
/// Synchronized method automatically acquire their associated lock around call.
|
/// Synchronized method automatically acquire their associated lock around call.
|
||||||
/// Can only be set in native method, (`[Self::is_native] = true`).
|
/// Can only be set in native method, (`[Self::is_native] = true`).
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_synchronized: bool,
|
pub is_synchronized: bool,
|
||||||
/// Bridge are automatically added by the compiler as a type-safe bridge.
|
/// Bridge are automatically added by the compiler as a type-safe bridge.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_bridge: bool,
|
pub is_bridge: bool,
|
||||||
/// If the last argument should be treated as a "rest" argument by compiler
|
/// If the last argument should be treated as a "rest" argument by compiler
|
||||||
/// (for method of variable number of argument).
|
/// (for method of variable number of argument).
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_varargs: bool,
|
pub is_varargs: bool,
|
||||||
/// If the method is a native method.
|
/// If the method is a native method.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_native: bool,
|
pub is_native: bool,
|
||||||
/// Abstract methods are not implemented by the class.
|
/// Abstract methods are not implemented by the class.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_abstract: bool,
|
pub is_abstract: bool,
|
||||||
/// If the method must use strict rules for floating point arithmetic.
|
/// If the method must use strict rules for floating point arithmetic.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_strictfp: bool,
|
pub is_strictfp: bool,
|
||||||
/// Synthetic method are not directly defined in the source code.
|
/// Synthetic method are not directly defined in the source code.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_synthetic: bool,
|
pub is_synthetic: bool,
|
||||||
/// If the method is a constructor.
|
/// If the method is a constructor.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_constructor: bool,
|
pub is_constructor: bool,
|
||||||
/// If the method is declared as synchronize (just indicatif)
|
/// If the method is declared as synchronize (just indicatif)
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub is_declared_syncrhonized: bool,
|
pub is_declared_syncrhonized: bool,
|
||||||
/// The annotations for this method
|
/// The annotations for this method
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub annotations: Vec<DexAnnotationItem>,
|
pub annotations: Vec<DexAnnotationItem>,
|
||||||
/// The annotations for the parameters of this method method
|
/// The annotations for the parameters of this method method
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub parameters_annotations: Vec<Vec<DexAnnotationItem>>,
|
pub parameters_annotations: Vec<Vec<DexAnnotationItem>>,
|
||||||
/// Hidden Api data.
|
/// Hidden Api data.
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub hiddenapi: Option<HiddenApiData>,
|
pub hiddenapi: Option<HiddenApiData>,
|
||||||
|
|
||||||
/// The code of the method
|
/// The code of the method
|
||||||
#[pyo3(get)]
|
#[cfg_attr(feature = "python", pyo3(get))]
|
||||||
pub code: Option<Code>,
|
pub code: Option<Code>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represent the visibility of a field
|
/// Represent the visibility of a field
|
||||||
#[pyclass(eq, eq_int)]
|
#[cfg_attr(feature = "python", pyclass(eq, eq_int))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub enum MethodVisibility {
|
pub enum MethodVisibility {
|
||||||
Public,
|
Public,
|
||||||
|
|
@ -81,18 +82,18 @@ pub enum MethodVisibility {
|
||||||
None_, // Actually quite common
|
None_, // Actually quite common
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl Method {
|
impl Method {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(descriptor: IdMethod) -> Self {
|
pub fn new(descriptor: IdMethod) -> Self {
|
||||||
// TODO: take code option as arg and set the default flags accordingly
|
// TODO: take code option as arg and set the default flags accordingly
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::dex_id::*;
|
use crate::dex_id::*;
|
||||||
|
|
@ -13,7 +14,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The structure use to reference a method invocation.
|
/// The structure use to reference a method invocation.
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||||
pub enum MethodHandle {
|
pub enum MethodHandle {
|
||||||
StaticPut { field: IdField },
|
StaticPut { field: IdField },
|
||||||
|
|
@ -78,13 +79,13 @@ impl<V: VisitorMut> VisitableMut<V> for MethodHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl MethodHandle {
|
impl MethodHandle {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,25 @@ use crate::{
|
||||||
DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Visitable,
|
DexString, DexValue, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Visitable,
|
||||||
VisitableMut, Visitor, VisitorMut,
|
VisitableMut, Visitor, VisitorMut,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexByte(pub i8);
|
pub struct DexByte(pub i8);
|
||||||
#[pymethods]
|
|
||||||
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexByte {
|
impl DexByte {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: i8) -> Self {
|
pub fn new(val: i8) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -42,21 +44,21 @@ impl DexByte {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexShort(pub i16);
|
pub struct DexShort(pub i16);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexShort {
|
impl DexShort {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: i16) -> Self {
|
pub fn new(val: i16) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -74,21 +76,21 @@ impl DexShort {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexChar(pub u16);
|
pub struct DexChar(pub u16);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexChar {
|
impl DexChar {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: u16) -> Self {
|
pub fn new(val: u16) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -106,21 +108,21 @@ impl DexChar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexInt(pub i32);
|
pub struct DexInt(pub i32);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexInt {
|
impl DexInt {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: i32) -> Self {
|
pub fn new(val: i32) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -138,21 +140,21 @@ impl DexInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexLong(pub i64);
|
pub struct DexLong(pub i64);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexLong {
|
impl DexLong {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: i64) -> Self {
|
pub fn new(val: i64) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -170,21 +172,21 @@ impl DexLong {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct DexFloat(pub f32);
|
pub struct DexFloat(pub f32);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexFloat {
|
impl DexFloat {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: f32) -> Self {
|
pub fn new(val: f32) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -202,21 +204,21 @@ impl DexFloat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct DexDouble(pub f64);
|
pub struct DexDouble(pub f64);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexDouble {
|
impl DexDouble {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: f64) -> Self {
|
pub fn new(val: f64) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -235,21 +237,21 @@ impl DexDouble {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DexString is already define in lib.rs, TODO: move the version in lib.rs here
|
/* DexString is already define in lib.rs, TODO: move the version in lib.rs here
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct DexString(pub u32);
|
pub struct DexString(pub u32);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexString {
|
impl DexString {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: u32) -> Self {
|
pub fn new(val: u32) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -268,21 +270,21 @@ impl DexString {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexNull;
|
pub struct DexNull;
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexNull {
|
impl DexNull {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn _new() -> Self {
|
pub fn _new() -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
@ -296,21 +298,21 @@ impl DexNull {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct DexBoolean(pub bool);
|
pub struct DexBoolean(pub bool);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexBoolean {
|
impl DexBoolean {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn new(val: bool) -> Self {
|
pub fn new(val: bool) -> Self {
|
||||||
Self(val)
|
Self(val)
|
||||||
}
|
}
|
||||||
|
|
@ -328,21 +330,21 @@ impl DexBoolean {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(eq)]
|
#[cfg_attr(feature = "python", pyclass(eq))]
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct DexArray(pub Vec<DexValue>);
|
pub struct DexArray(pub Vec<DexValue>);
|
||||||
#[pymethods]
|
#[cfg_attr(feature = "python", pymethods)]
|
||||||
impl DexArray {
|
impl DexArray {
|
||||||
pub fn to_json(&self) -> Result<String> {
|
pub fn to_json(&self) -> Result<String> {
|
||||||
Ok(serde_json::to_string(self)?)
|
Ok(serde_json::to_string(self)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[staticmethod]
|
#[cfg_attr(feature = "python", staticmethod)]
|
||||||
pub fn from_json(json: &str) -> Result<Self> {
|
pub fn from_json(json: &str) -> Result<Self> {
|
||||||
Ok(serde_json::from_str(json)?)
|
Ok(serde_json::from_str(json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[new]
|
#[cfg_attr(feature = "python", new)]
|
||||||
pub fn _new(arr: Vec<DexValue>) -> Self {
|
pub fn _new(arr: Vec<DexValue>) -> Self {
|
||||||
Self(arr)
|
Self(arr)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use pyo3::exceptions::PyTypeError;
|
#[cfg(feature = "python")]
|
||||||
use pyo3::prelude::*;
|
use pyo3::{exceptions::PyTypeError, prelude::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dex_id::*, scalar::*, DexAnnotation, DexString, MethodHandle, Result, Visitable, VisitableMut,
|
dex_id::*, scalar::*, DexAnnotation, DexString, MethodHandle, Result, Visitable, VisitableMut,
|
||||||
|
|
@ -83,6 +83,7 @@ impl<V: VisitorMut> VisitableMut<V> for DexValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "python")]
|
||||||
impl<'source> FromPyObject<'source> for DexValue {
|
impl<'source> FromPyObject<'source> for DexValue {
|
||||||
fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult<Self> {
|
fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult<Self> {
|
||||||
if let Ok(val) = DexByte::extract_bound(ob) {
|
if let Ok(val) = DexByte::extract_bound(ob) {
|
||||||
|
|
@ -305,7 +306,7 @@ impl DexValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "python")]
|
||||||
impl<'py> IntoPyObject<'py> for DexValue {
|
impl<'py> IntoPyObject<'py> for DexValue {
|
||||||
type Target = PyAny;
|
type Target = PyAny;
|
||||||
type Output = Bound<'py, Self::Target>;
|
type Output = Bound<'py, Self::Target>;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue