Skip to content

Commit 0b9c763

Browse files
authored
Allow referring to static methods directly (#392)
1 parent 3967f44 commit 0b9c763

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

src/basilisp/core/__init__.lpy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,13 +1204,13 @@
12041204
map entry containing key and value."
12051205
([coll]
12061206
(if (= 2 (count coll))
1207-
((.-from-vec basilisp.lang.map/MapEntry) coll)
1207+
(basilisp.lang.map.MapEntry/from-vec coll)
12081208
(throw
12091209
(ex-info "Cannot coerce object to basilisp.lang.map.MapEntry"
12101210
{:coll coll
12111211
:type (type coll)}))))
12121212
([k v]
1213-
((.-of basilisp.lang.map/MapEntry) k v)))
1213+
(basilisp.lang.map.MapEntry/of k v)))
12141214

12151215
(defn key
12161216
"Return the key from a map entry."
@@ -1920,7 +1920,7 @@
19201920
attempting to change the root binding of this var will not
19211921
change the default data readers."}
19221922
default-data-readers
1923-
(.--DATA-READERS basilisp.lang.reader/ReaderContext))
1923+
basilisp.lang.reader.ReaderContext/_DATA_READERS)
19241924

19251925
(def
19261926
^{:doc "Data readers map which will be merged in to the default data

src/basilisp/lang/compiler/analyzer.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,9 +2044,28 @@ def _list_node(ctx: AnalyzerContext, form: ISeq) -> Node:
20442044
return _invoke_ast(ctx, form)
20452045

20462046

2047+
def _resolve_nested_symbol(ctx: AnalyzerContext, form: sym.Symbol) -> HostField:
2048+
"""Resolve an attribute by recursively accessing the parent object
2049+
as if it were its own namespaced symbol."""
2050+
assert form.ns is not None
2051+
assert "." in form.ns
2052+
2053+
parent_ns, parent_name = form.ns.rsplit(".", maxsplit=1)
2054+
parent = sym.symbol(parent_name, ns=parent_ns)
2055+
parent_node = __resolve_namespaced_symbol(ctx, parent)
2056+
2057+
return HostField(
2058+
form,
2059+
field=form.name,
2060+
target=parent_node,
2061+
is_assignable=True,
2062+
env=ctx.get_node_env(),
2063+
)
2064+
2065+
20472066
def __resolve_namespaced_symbol( # pylint: disable=too-many-branches
20482067
ctx: AnalyzerContext, form: sym.Symbol
2049-
) -> Union[MaybeClass, MaybeHostForm, VarRef]:
2068+
) -> Union[HostField, MaybeClass, MaybeHostForm, VarRef]:
20502069
"""Resolve a namespaced symbol into a Python name or Basilisp Var."""
20512070
assert form.ns is not None
20522071

@@ -2129,6 +2148,8 @@ def __resolve_namespaced_symbol( # pylint: disable=too-many-branches
21292148
form=form,
21302149
)
21312150
return VarRef(form=form, var=v, env=ctx.get_node_env())
2151+
elif "." in form.ns:
2152+
return _resolve_nested_symbol(ctx, form)
21322153
else:
21332154
raise AnalyzerException(
21342155
f"unable to resolve symbol '{form}' in this context", form=form
@@ -2169,7 +2190,7 @@ def __resolve_bare_symbol(
21692190

21702191
def _resolve_sym(
21712192
ctx: AnalyzerContext, form: sym.Symbol
2172-
) -> Union[MaybeClass, MaybeHostForm, VarRef]:
2193+
) -> Union[HostField, MaybeClass, MaybeHostForm, VarRef]:
21732194
"""Resolve a Basilisp symbol as a Var or Python name."""
21742195
# Support special class-name syntax to instantiate new classes
21752196
# (Classname. *args)
@@ -2190,7 +2211,7 @@ def _resolve_sym(
21902211

21912212
def _symbol_node(
21922213
ctx: AnalyzerContext, form: sym.Symbol
2193-
) -> Union[Const, Local, MaybeClass, MaybeHostForm, VarRef]:
2214+
) -> Union[Const, HostField, Local, MaybeClass, MaybeHostForm, VarRef]:
21942215
if ctx.is_quoted:
21952216
return _const_node(ctx, form)
21962217

src/basilisp/lang/compiler/nodes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,8 @@ class HostCall(Node[SpecialForm]):
435435

436436

437437
@attr.s(auto_attribs=True, frozen=True, slots=True)
438-
class HostField(Node[SpecialForm], Assignable):
439-
form: SpecialForm
438+
class HostField(Node[Union[SpecialForm, sym.Symbol]], Assignable):
439+
form: Union[SpecialForm, sym.Symbol]
440440
field: str
441441
target: Node
442442
env: NodeEnv

tests/basilisp/compiler_test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,13 @@ def test_namespaced_sym_cannot_resolve(self, ns: runtime.Namespace):
27692769
with pytest.raises(compiler.CompilerException):
27702770
lcompile("other.ns/name")
27712771

2772+
def test_nested_namespaced_sym_will_resolve(self, ns: runtime.Namespace):
2773+
assert lmap.MapEntry.of is lcompile("basilisp.lang.map.MapEntry/of")
2774+
2775+
def test_nested_bare_sym_will_not_resolve(self, ns: runtime.Namespace):
2776+
with pytest.raises(compiler.CompilerException):
2777+
lcompile("basilisp.lang.map.MapEntry.of")
2778+
27722779
def test_aliased_var_does_not_resolve(self, ns: runtime.Namespace):
27732780
current_ns: runtime.Namespace = ns
27742781
other_ns_name = sym.symbol("other.ns")

0 commit comments

Comments
 (0)