Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure paths are normalised in Puya source maps #344

Merged
merged 2 commits into from
Nov 4, 2024
Merged
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: 3 additions & 0 deletions examples/hello_world/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# allow source maps in this directory, so we have at least once source map in approvals
# to ensure path normalization is covered
!out_02/*.puya.map
54 changes: 54 additions & 0 deletions examples/hello_world/out_O2/HelloWorldContract.approval.puya.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"version": 3,
"sources": [
"../contract.py"
],
"mappings": ";AAMY;;;;;;;;;AADG;;;AACH;AAAJ;AACO;;AAAP",
"op_pc_offset": 0,
"pc_events": {
"1": {
"subroutine": "examples.hello_world.contract.HelloWorldContract.approval_program",
"params": {},
"block": "examples.hello_world.contract.HelloWorldContract.approval_program",
"stack_in": [],
"op": "pushbytes 0x48656c6c6f2c20"
},
"10": {
"op": "txna ApplicationArgs 0",
"defined_out": [
"0x48656c6c6f2c20",
"name#0"
],
"stack_out": [
"0x48656c6c6f2c20",
"name#0"
]
},
"13": {
"op": "concat",
"defined_out": [
"tmp%0#0"
],
"stack_out": [
"tmp%0#0"
]
},
"14": {
"op": "log",
"stack_out": []
},
"15": {
"op": "pushint 1 // 1",
"defined_out": [
"1"
],
"stack_out": [
"1"
]
},
"17": {
"op": "return",
"stack_out": []
}
}
}
27 changes: 27 additions & 0 deletions examples/hello_world/out_O2/HelloWorldContract.clear.puya.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"version": 3,
"sources": [
"../contract.py"
],
"mappings": ";AAUe;;AAAP",
"op_pc_offset": 0,
"pc_events": {
"1": {
"subroutine": "examples.hello_world.contract.HelloWorldContract.clear_state_program",
"params": {},
"block": "examples.hello_world.contract.HelloWorldContract.clear_state_program",
"stack_in": [],
"op": "pushint 1 // 1",
"defined_out": [
"1"
],
"stack_out": [
"1"
]
},
"3": {
"op": "return",
"stack_out": []
}
}
}
14 changes: 5 additions & 9 deletions src/puya/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from puya.teal.models import TealProgram, TealSubroutine
from puya.teal.output import emit_teal
from puya.ussemble.main import assemble_program
from puya.utils import attrs_extend, make_path_relative_to_cwd
from puya.utils import attrs_extend, make_path_relative_to, make_path_relative_to_cwd

logger = log.get_logger(__name__)

Expand Down Expand Up @@ -334,19 +334,15 @@ def _write_artifacts(
def _debug_info_as_json(info: DebugInfo, base_path: Path) -> bytes:
# make sources relative to output
info = attrs.evolve(
info, sources=[str(_try_make_relative_to(Path(s), base_path)) for s in info.sources]
info,
sources=[
make_path_relative_to(path=Path(s), to=base_path, walk_up=True) for s in info.sources
],
)
json = _debug_info_converter.dumps(info, DebugInfo, indent=2)
return json.encode("utf-8")


def _try_make_relative_to(path: Path, relative_to: Path) -> Path:
try:
return path.relative_to(relative_to, walk_up=True)
except ValueError:
return path


def _write_output(base_path: Path, programs: dict[str, bytes | None]) -> None:
for suffix, program in programs.items():
output_path = base_path.with_suffix(suffix)
Expand Down
5 changes: 3 additions & 2 deletions src/puya/ussemble/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from puya.parse import SourceLocation
from puya.ussemble import models
from puya.ussemble.context import AssembleContext
from puya.utils import normalize_path


def build_debug_info(
Expand All @@ -28,7 +29,7 @@ def build_debug_info(
pc - pc_offset: node.source_location for pc, node in pc_ops.items() if pc >= pc_offset
}

files = sorted(map(str, {s.file for s in source_map.values() if s and s.file}))
files = sorted(map(normalize_path, {s.file for s in source_map.values() if s and s.file}))
mappings = _get_src_mappings(source_map, files)

return DebugInfo(
Expand All @@ -53,7 +54,7 @@ def _get_src_mappings(
if not loc or not loc.file:
mappings.append("")
continue
source_index = files.index(str(loc.file))
source_index = files.index(normalize_path(loc.file))
line = loc.line - 1 # make 0-indexed
column = loc.column or 0

Expand Down
12 changes: 8 additions & 4 deletions src/puya/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,14 @@ def attrs_extend[


@functools.cache
def _make_path_relative(*, to: Path, path: Path) -> str:
def make_path_relative_to(*, to: Path, path: Path, walk_up: bool = False) -> str:
with contextlib.suppress(ValueError):
path = path.relative_to(to)
return str(path).replace(os.sep, "/")
path = path.relative_to(to, walk_up=walk_up)
return normalize_path(path)


def make_path_relative_to_cwd(path: Path) -> str:
return _make_path_relative(to=Path.cwd(), path=path)
return make_path_relative_to(to=Path.cwd(), path=path)


def unique[T](items: Iterable[T]) -> list[T]:
Expand Down Expand Up @@ -324,3 +324,7 @@ def set_remove[T](set_: MutableSet[T], value: T) -> bool:
removed = value in set_
set_.discard(value)
return removed


def normalize_path(path: Path) -> str:
return str(path).replace(os.sep, "/")
Loading