Skip to content

Commit

Permalink
Include orphaned definitions in the file dump
Browse files Browse the repository at this point in the history
  • Loading branch information
jac3km4 committed Feb 7, 2021
1 parent 813e414 commit 59d4a62
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn decompile(opts: DecompileOpts) -> Result<(), Error> {

if opts.dump_files {
for entry in FileIndex::from_pool(pool).iter() {
let path = opts.output.as_path().join(&entry.file.path);
let path = opts.output.as_path().join(&entry.path);

std::fs::create_dir_all(path.parent().unwrap())?;
let mut output = BufWriter::new(File::create(path)?);
Expand Down
34 changes: 29 additions & 5 deletions decompiler/src/files.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::collections::{HashMap, HashSet};
use std::iter::{once, FromIterator};
use std::path::Path;

use redscript::bundle::{ConstantPool, PoolIndex};
use redscript::definition::{Definition, DefinitionValue, SourceFile};
use redscript::definition::{Definition, DefinitionValue};

pub struct FileIndex<'a> {
file_map: HashMap<PoolIndex<Definition>, HashSet<PoolIndex<Definition>>>,
Expand All @@ -29,24 +30,47 @@ impl<'a> FileIndex<'a> {
}

pub fn iter(&'a self) -> impl Iterator<Item = FileEntry<'a>> {
self.file_map.iter().filter_map(move |(idx, children)| {
let source_files = self.file_map.iter().filter_map(move |(idx, children)| {
if let DefinitionValue::SourceFile(ref file) = self.pool.definition(*idx).unwrap().value {
let mut definitions: Vec<&Definition> = children
.iter()
.filter_map(|child| self.pool.definition(*child).ok())
.collect();
definitions.sort_by_key(|def| def.first_line(self.pool).unwrap_or(0));

let entry = FileEntry { file, definitions };
let entry = FileEntry {
path: &file.path,
definitions,
};
Some(entry)
} else {
None
}
})
});

once(self.orphans()).chain(source_files)
}

fn orphans(&'a self) -> FileEntry<'a> {
let definitions = self
.pool
.definitions()
.filter(|(_, def)| match &def.value {
DefinitionValue::Class(cls) if cls.functions.is_empty() || cls.flags.is_native() => true,
DefinitionValue::Enum(_) => true,
DefinitionValue::Function(fun) if def.parent == PoolIndex::UNDEFINED && fun.flags.is_native() => true,
_ => false,
})
.map(|(_, def)| def)
.collect();
FileEntry {
path: Path::new("orphans.script"),
definitions,
}
}
}

pub struct FileEntry<'a> {
pub file: &'a SourceFile,
pub path: &'a Path,
pub definitions: Vec<&'a Definition>,
}

0 comments on commit 59d4a62

Please sign in to comment.