Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions mypy.ini

This file was deleted.

58 changes: 58 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,61 @@ features = ["dev"]

[project.scripts]
splat = "splat.__main__:splat_main"


[tool.mypy]
files = ["src"]
enable_error_code = [
"truthy-bool",
"mutable-override",
"exhaustive-match",
]
show_column_numbers = true
show_error_codes = true
show_traceback = true
disallow_any_decorated = true
disallow_any_unimported = false # TODO: change true
ignore_missing_imports = true
local_partial_types = true
no_implicit_optional = true
#strict = true
warn_unreachable = true
check_untyped_defs = false # TODO: change true

[tool.ruff]
#line-length = 79
fix = true

include = ["*.py", "*.pyi", "**/pyproject.toml"]

[tool.ruff.lint]
extend-select = [
#"A", # flake8-builtins
#"COM", # flake8-commas
"E", # Error
"FA", # flake8-future-annotations
#"I", # isort
"ICN", # flake8-import-conventions
"PYI", # flake8-pyi
"R", # Refactor
"RET", # flake8-return
"RUF", # Ruff-specific rules
#"SIM", # flake8-simplify
"SLOT", # flake8-slots
"TCH", # flake8-type-checking
"UP", # pyupgrade
"W", # Warning
"YTT", # flake8-2020
]
extend-ignore = [
"E501", # line-too-long
"PYI041", # redundant-numeric-union
"SIM117", # multiple-with-statements
]

[tool.ruff.lint.per-file-ignores]
"tests/*" = [
"D100", # undocumented-public-module
"D103", # undocumented-public-function
"D107", # undocumented-public-init
]
2 changes: 1 addition & 1 deletion src/splat/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import splat


def splat_main():
def splat_main() -> None:
parser = argparse.ArgumentParser(
description="A binary splitting tool to assist with decompilation and modding projects",
prog="splat",
Expand Down
9 changes: 6 additions & 3 deletions src/splat/disassembler/disassembler.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Set


class Disassembler(ABC):
__slots__ = ()

@abstractmethod
def configure(self):
def configure(self) -> None:
raise NotImplementedError("configure")

@abstractmethod
def check_version(self, skip_version_check: bool, splat_version: str):
raise NotImplementedError("check_version")

@abstractmethod
def known_types(self) -> Set[str]:
def known_types(self) -> set[str]:
raise NotImplementedError("known_types")
1 change: 0 additions & 1 deletion src/splat/disassembler/disassembler_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ def get_instance() -> Disassembler:
global __initialized
if not __initialized:
raise Exception("Disassembler instance not initialized")
return None
return __instance
122 changes: 63 additions & 59 deletions src/splat/disassembler/disassembler_section.py
Original file line number Diff line number Diff line change
@@ -1,94 +1,99 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Optional

import spimdisasm

from ..util import options, symbols


class DisassemblerSection(ABC):
__slots__ = ()

@abstractmethod
def disassemble(self):
def disassemble(self) -> str:
raise NotImplementedError("disassemble")

@abstractmethod
def analyze(self):
def analyze(self) -> None:
raise NotImplementedError("analyze")

@abstractmethod
def set_comment_offset(self, rom_start: int):
def set_comment_offset(self, rom_start: int) -> None:
raise NotImplementedError("set_comment_offset")

@abstractmethod
def make_bss_section(
self,
rom_start,
rom_end,
vram_start,
bss_end,
name,
segment_rom_start,
exclusive_ram_id,
):
rom_start: int,
rom_end: int,
vram_start: int,
bss_end: int,
name: str,
segment_rom_start: int,
exclusive_ram_id: str | None,
) -> None:
raise NotImplementedError("make_bss_section")

@abstractmethod
def make_data_section(
self,
rom_start,
rom_end,
vram_start,
name,
rom_bytes,
segment_rom_start,
exclusive_ram_id,
):
rom_start: int,
rom_end: int,
vram_start: int,
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id: str | None,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the PR makes use of this union syntax a lot but this was actually introduced in python 3.10 (source), unlike splat which (according to angheloalf) supports 3.9

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this is not a problem because of using from __future__ import annotations. Anything that's trying to use annotations at runtime uses something like typing.get_type_hints, which deals with string versions of annotations properly.

) -> None:
raise NotImplementedError("make_data_section")

@abstractmethod
def get_section(self):
def get_section(self) -> spimdisasm.mips.sections.SectionBase | None:
raise NotImplementedError("get_section")

@abstractmethod
def make_rodata_section(
self,
rom_start,
rom_end,
vram_start,
name,
rom_bytes,
segment_rom_start,
exclusive_ram_id,
):
rom_start: int,
rom_end: int,
vram_start: int,
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id: str | None,
) -> None:
raise NotImplementedError("make_rodata_section")

@abstractmethod
def make_text_section(
self,
rom_start,
rom_end,
vram_start,
name,
rom_bytes,
segment_rom_start,
exclusive_ram_id,
):
rom_start: int,
rom_end: int,
vram_start: int,
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id: str | None,
) -> None:
raise NotImplementedError("make_text_section")


class SpimdisasmDisassemberSection(DisassemblerSection):
def __init__(self):
self.spim_section: Optional[spimdisasm.mips.sections.SectionBase] = None
__slots__ = ("spim_section",)

def __init__(self) -> None:
self.spim_section: spimdisasm.mips.sections.SectionBase | None = None

def disassemble(self) -> str:
assert self.spim_section is not None
return self.spim_section.disassemble()

def analyze(self):
def analyze(self) -> None:
assert self.spim_section is not None
self.spim_section.analyze()

def set_comment_offset(self, rom_start: int):
def set_comment_offset(self, rom_start: int) -> None:
assert self.spim_section is not None
self.spim_section.setCommentOffset(rom_start)

Expand All @@ -100,8 +105,8 @@ def make_bss_section(
bss_end: int,
name: str,
segment_rom_start: int,
exclusive_ram_id,
):
exclusive_ram_id: str | None,
) -> None:
self.spim_section = spimdisasm.mips.sections.SectionBss(
symbols.spim_context,
rom_start,
Expand All @@ -121,8 +126,8 @@ def make_data_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
):
exclusive_ram_id: str | None,
) -> None:
self.spim_section = spimdisasm.mips.sections.SectionData(
symbols.spim_context,
rom_start,
Expand All @@ -134,7 +139,7 @@ def make_data_section(
exclusive_ram_id,
)

def get_section(self) -> Optional[spimdisasm.mips.sections.SectionBase]:
def get_section(self) -> spimdisasm.mips.sections.SectionBase | None:
return self.spim_section

def make_rodata_section(
Expand All @@ -145,8 +150,8 @@ def make_rodata_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
):
exclusive_ram_id: str | None,
) -> None:
self.spim_section = spimdisasm.mips.sections.SectionRodata(
symbols.spim_context,
rom_start,
Expand All @@ -166,8 +171,8 @@ def make_text_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
):
exclusive_ram_id: str | None,
) -> None:
self.spim_section = spimdisasm.mips.sections.SectionText(
symbols.spim_context,
rom_start,
Expand All @@ -187,8 +192,8 @@ def make_gcc_except_table_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
):
exclusive_ram_id: str | None,
) -> None:
self.spim_section = spimdisasm.mips.sections.SectionGccExceptTable(
symbols.spim_context,
rom_start,
Expand All @@ -201,12 +206,11 @@ def make_gcc_except_table_section(
)


def make_disassembler_section() -> Optional[SpimdisasmDisassemberSection]:
def make_disassembler_section() -> SpimdisasmDisassemberSection | None:
if options.opts.platform in ["n64", "psx", "ps2", "psp"]:
return SpimdisasmDisassemberSection()

raise NotImplementedError("No disassembler section for requested platform")
return None


def make_text_section(
Expand All @@ -216,7 +220,7 @@ def make_text_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
exclusive_ram_id: str | None,
) -> DisassemblerSection:
section = make_disassembler_section()
assert section is not None
Expand All @@ -239,7 +243,7 @@ def make_data_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
exclusive_ram_id: str | None,
) -> DisassemblerSection:
section = make_disassembler_section()
assert section is not None
Expand All @@ -262,7 +266,7 @@ def make_rodata_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
exclusive_ram_id: str | None,
) -> DisassemblerSection:
section = make_disassembler_section()
assert section is not None
Expand All @@ -285,7 +289,7 @@ def make_bss_section(
bss_end: int,
name: str,
segment_rom_start: int,
exclusive_ram_id,
exclusive_ram_id: str | None,
) -> DisassemblerSection:
section = make_disassembler_section()
assert section is not None
Expand All @@ -308,7 +312,7 @@ def make_gcc_except_table_section(
name: str,
rom_bytes: bytes,
segment_rom_start: int,
exclusive_ram_id,
exclusive_ram_id: str | None,
) -> DisassemblerSection:
section = make_disassembler_section()
assert section is not None
Expand Down
9 changes: 6 additions & 3 deletions src/splat/disassembler/null_disassembler.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from __future__ import annotations

from . import disassembler
from typing import Set


class NullDisassembler(disassembler.Disassembler):
def configure(self):
__slots__ = ()

def configure(self) -> None:
pass

def check_version(self, skip_version_check: bool, splat_version: str):
pass

def known_types(self) -> Set[str]:
def known_types(self) -> set[str]:
return set()
Loading