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
12 changes: 8 additions & 4 deletions spy/backend/spy.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ def dump_mod(self, modname: str) -> str:
):
aliases.append((attr, w_obj))
for attr, w_obj in aliases:
fqn_str = w_obj.fqn.human_name(self.vm)
self.out.wl(f"{attr} = `{fqn_str}`")
fqn_str = self.fmt_fqn(w_obj.fqn)
self.out.wl(f"{attr} = {fqn_str}")
if aliases:
self.out.wl()

Expand Down Expand Up @@ -153,7 +153,7 @@ def fmt_w_obj(self, w_obj: W_Object) -> str:
if isinstance(w_obj, W_Type) and issubclass(w_obj.pyclass, W_InterpList):
# this is a ugly special case for now, we need to find a better
# solution
return w_obj.fqn.human_name(self.vm)
return self.fmt_fqn(w_obj.fqn)
#
# this assumes that w_obj has a valid FQN
fqn = self.vm.reverse_lookup_global(w_obj)
Expand All @@ -164,7 +164,11 @@ def fmt_fqn(self, fqn: FQN) -> str:
if self.fqn_format == "full":
name = str(fqn)
elif self.fqn_format == "short":
name = fqn.human_name(self.vm) # don't show builtins::
# don't show builtins::, and don't repeat the current module
# name for FQNs nested inside it (at any depth, including
# inside generic qualifiers)
parent = FQN(self.modname) if self.modname else None
name = fqn.human_name(self.vm, parent=parent)
else:
assert False
#
Expand Down
29 changes: 21 additions & 8 deletions spy/fqn.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,14 @@ def _fullname(self, human: bool) -> str:
def fullname(self) -> str:
return self._fullname(human=False)

def _human_render(self) -> str:
def _human_render(self, parent: Optional["FQN"] = None) -> str:
"""
Render a FQN to string, special casing builtins::, def, etc.

If `parent` is given and `self` starts with `parent`'s parts, that common
prefix is stripped from the rendered output. The match is on the
structured NSPart tuples, not on the rendered string, so it can never
misfire on a merely-similar-looking name.
"""
is_def = (
len(self.parts) == 2
Expand All @@ -225,7 +230,7 @@ def _human_render(self) -> str:
d = "@blue.generic def"
else:
d = "@blue.metafunc def"
quals = [q._human_render() for q in p1.qualifiers]
quals = [q._human_render(parent) for q in p1.qualifiers]
p = ", ".join(quals[:-1])
r = quals[-1]
if r == "types::NoneType":
Expand All @@ -240,19 +245,22 @@ def _human_render(self) -> str:
if is_varargs_param:
p1 = self.parts[1]
assert len(p1.qualifiers) == 1
return f"*{p1.qualifiers[0]._human_render()}"
return f"*{p1.qualifiers[0]._human_render(parent)}"

parts = self.parts
if str(parts[0]) == "builtins":
parts = parts[1:]
elif parent is not None and parent.parts:
pparts = parent.parts
if len(parts) > len(pparts) and parts[: len(pparts)] == pparts:
parts = parts[len(pparts) :]

rendered = []
for part in parts:
name = part.name
if part.qualifiers:
name = (
f"{name}[{', '.join(q._human_render() for q in part.qualifiers)}]"
)
quals_str = ", ".join(q._human_render(parent) for q in part.qualifiers)
name = f"{name}[{quals_str}]"
if part.suffix:
name += f"#{part.suffix}"
rendered.append(name)
Expand Down Expand Up @@ -323,13 +331,18 @@ def debug_human_name(self) -> str:
"""
return self._human_render()

def human_name(self, vm: Any) -> str:
def human_name(self, vm: Any, parent: Optional["FQN"] = None) -> str:
"""
Render the FQN for end-user display, honoring vm.fqn_human_aliases.
If no VM is available, use debug_human_name instead.

If `parent` is given, it is stripped from the output wherever it
appears as a genuine namespace prefix (see _human_render).
"""
human_fqn = self._resolve_aliases(vm, frozenset())
return human_fqn._human_render()
if parent is not None:
parent = parent._resolve_aliases(vm, frozenset())
return human_fqn._human_render(parent)

def human_symbol_name(self, vm: Any) -> str:
human_fqn = self._resolve_aliases(vm, frozenset())
Expand Down
48 changes: 24 additions & 24 deletions spy/tests/compiler/test_linearize.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ def foo() -> i32:
if self.backend == "linearize":
expected = """
def foo() -> i32:
$v0: i32 = `test::f1`()
$v1: i32 = `test::f2`()
return `test::sub`($v0, $v1)
$v0: i32 = f1()
$v1: i32 = f2()
return sub($v0, $v1)
"""
self.assert_linearize("foo", expected)

Expand All @@ -92,7 +92,7 @@ def foo(x: i32) -> i32:
if self.backend == "linearize":
expected = """
def foo(x: i32) -> i32:
return `test::add`(x + 1, x + 2)
return add(x + 1, x + 2)
"""
self.assert_linearize("foo", expected)

Expand Down Expand Up @@ -122,8 +122,8 @@ def foo(a: i32, c: i32, d: i32) -> i32:
expected = """
def foo(a: i32, c: i32, d: i32) -> i32:
$v0: i32 = a
$v1: i32 = `test::g`()
return `test::bar`($v0, 1 + $v1, c, d)
$v1: i32 = g()
return bar($v0, 1 + $v1, c, d)
"""
self.assert_linearize("foo", expected)

Expand All @@ -147,7 +147,7 @@ def foo(a: i32) -> i32:
if self.backend == "linearize":
expected = """
def foo(a: i32) -> i32:
return `test::foo4`(a, 100, `test::V`, a)
return foo4(a, 100, V, a)
"""
self.assert_linearize("foo", expected)

Expand All @@ -170,7 +170,7 @@ def foo(x: bool) -> i32:
expected = """
def foo(x: bool) -> i32:
if x:
return `test::g`()
return g()
else:
return 0
"""
Expand All @@ -193,7 +193,7 @@ def foo() -> i32:
expected = """
def foo() -> i32:
x: i32 = 0
x = `test::g`()
x = g()
return x
"""
self.assert_linearize("foo", expected)
Expand Down Expand Up @@ -231,7 +231,7 @@ def f2(x: bool) -> bool:
expected_f1 = """
def f1(x: bool) -> bool:
if x:
y: bool = `test::side_effect`()
y: bool = side_effect()
$v0: bool = y
else:
$v0 = x
Expand All @@ -240,7 +240,7 @@ def f1(x: bool) -> bool:
self.assert_linearize("f1", expected_f1)
expected_f2 = """
def f2(x: bool) -> bool:
return x and `test::side_effect`()
return x and side_effect()
"""
self.assert_linearize("f2", expected_f2)

Expand Down Expand Up @@ -270,7 +270,7 @@ def foo(x: bool) -> bool:
if x:
$v0: bool = x
else:
y: bool = `test::side_effect`()
y: bool = side_effect()
$v0 = y
return $v0
"""
Expand Down Expand Up @@ -350,11 +350,11 @@ def foo() -> i32:
expected = """
def foo() -> i32:
while True:
$v0: i32 = `test::tick`()
$v0: i32 = tick()
if `operator::bool_not`($v0 < 3):
break
`_print::println[i32]`(`test::N`)
return `test::N`
`_print::println[i32]`(N)
return N
"""
self.assert_linearize("foo", expected)

Expand All @@ -380,9 +380,9 @@ def foo(x: i32) -> i32:
expected = """
def foo(x: i32) -> i32:
$v0: i32 = x
$v1: i32 = `test::g`()
$v1: i32 = g()
$v2: i32 = x := $v1
return `test::foo3`($v0, $v2, x)
return foo3($v0, $v2, x)
"""
self.assert_linearize("foo", expected)

Expand All @@ -405,10 +405,10 @@ def foo() -> i32:
if self.backend == "linearize":
expected = """
def foo() -> i32:
$v0: i32 = `test::V`
$v1: i32 = `test::g`()
$v2: i32 = `test::V` := $v1
return `test::foo3`($v0, $v2, `test::V`)
$v0: i32 = V
$v1: i32 = g()
$v2: i32 = V := $v1
return foo3($v0, $v2, V)
"""
self.assert_linearize("foo", expected)

Expand Down Expand Up @@ -495,11 +495,11 @@ def foo() -> i32:
if self.backend == "linearize":
expected = """
def foo() -> i32:
a: i32 = `test::f`()
a: i32 = f()
$v0: i32 = a
b: i32 = `test::g`()
b: i32 = g()
$v1: i32 = b
return `test::add`($v0, $v1)
return add($v0, $v1)
"""
self.assert_linearize("foo", expected)

Expand Down
8 changes: 4 additions & 4 deletions spy/tests/test_backend_spy.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,13 @@ def foo() -> None:
add_f64(3.4, 5.6)
""")
self.assert_dump("""
add_i32 = `test::add[i32]`
add_f64 = `test::add[f64]`
add_i32 = `add[i32]`
add_f64 = `add[f64]`

def `test::add[i32]`(x: i32, y: i32) -> i32:
def `add[i32]`(x: i32, y: i32) -> i32:
return x + y

def `test::add[f64]`(x: f64, y: f64) -> f64:
def `add[f64]`(x: f64, y: f64) -> f64:
return x + y

def foo() -> None:
Expand Down
36 changes: 18 additions & 18 deletions spy/tests/test_doppler.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def inc(x: i32) -> i32:
return x + 1

def foo() -> i32:
return `test::inc`(5)
return inc(5)
"""
self.redshift(src)
self.assert_dump(expected)
Expand Down Expand Up @@ -172,7 +172,7 @@ def inc(x: i32) -> i32:

def foo() -> i32:
x: i32 = 0
y: i32 = `test::inc`(x := 1)
y: i32 = inc(x := 1)
return x + y
""")

Expand All @@ -194,8 +194,8 @@ def foo(x: i32) -> None:

def main() -> None:
x: i32 = 0
`test::foo`(x := 1)
`test::foo`(2)
foo(x := 1)
foo(2)
`_print::println[i32]`(x)
`_print::println[str]`('2')
""")
Expand All @@ -213,9 +213,9 @@ def foo() -> i32:
""")
self.assert_dump("""
def foo() -> i32:
return `test::make_fn::fn`(21)
return `make_fn::fn`(21)

def `test::make_fn::fn`(x: i32) -> i32:
def `make_fn::fn`(x: i32) -> i32:
return x * 2
""")

Expand All @@ -236,14 +236,14 @@ def main() -> None:
""")
self.assert_dump("""
def main() -> None:
`test::make_foo::foo`()
`make_foo::foo`()

def `test::make_foo::fn`() -> None:
def `make_foo::fn`() -> None:
`_print::println[str]`('fn')

def `test::make_foo::foo`() -> None:
`test::make_foo::fn`()
`test::make_foo::fn`()
def `make_foo::foo`() -> None:
`make_foo::fn`()
`make_foo::fn`()
""")

def test_binops(self):
Expand Down Expand Up @@ -312,13 +312,13 @@ def foo() -> None:
""")
self.assert_dump("""
def foo() -> None:
x: i32 = `test::add[i32]::impl`(1, 2)
y: str = `test::add[str]::impl`('a', 'b')
x: i32 = `add[i32]::impl`(1, 2)
y: str = `add[str]::impl`('a', 'b')

def `test::add[i32]::impl`(x: i32, y: i32) -> i32:
def `add[i32]::impl`(x: i32, y: i32) -> i32:
return x + y

def `test::add[str]::impl`(x: str, y: str) -> str:
def `add[str]::impl`(x: str, y: str) -> str:
return `_str::methods::__add__`(x, y)
""")

Expand All @@ -330,7 +330,7 @@ def foo() -> None:
""")
self.assert_dump("""
def foo() -> None:
`test::x` = 1
x = 1
""")

def test_format_prebuilt_exception(self):
Expand Down Expand Up @@ -538,7 +538,7 @@ def bar(x: f64) -> None:
pass

def foo(x: i32) -> f64:
`test::bar`(`operator::i32_to_f64`(x))
bar(`operator::i32_to_f64`(x))
flag: bool = `operator::i32_to_bool`(x)
if `operator::i32_to_bool`(x):
pass
Expand All @@ -564,7 +564,7 @@ def bar(x: f64) -> None:
pass

def foo() -> f64:
`test::bar`(42.0)
bar(42.0)
flag: bool = True
if True:
pass
Expand Down
Loading