Skip to content

Commit 5085a9b

Browse files
committed
Fix handling of wildcards in type dependency analysis
1 parent 5e98f65 commit 5085a9b

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/analysis/type_dependency_analysis.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,22 @@ def visit_variable(self, node):
463463
DeclarationNode("/".join(namespace), decl)
464464
)
465465

466+
def _get_receiver_type(self, receiver_t):
467+
# If the receiver type is parameterized, compute type variable
468+
# assignments.
469+
if receiver_t.is_parameterized():
470+
return receiver_t, receiver_t.get_type_variable_assignments()
471+
472+
# If the receiver type is a type variable, compute its bound.
473+
if receiver_t.is_type_var():
474+
receiver_t = receiver_t.get_bound_rec(self._bt_factory)
475+
return receiver_t, {}
476+
477+
if receiver_t.is_wildcard():
478+
return self._get_receiver_type(receiver_t.get_bound_rec())
479+
480+
return receiver_t, {}
481+
466482
def _visit_assign_with_receiver(self, node):
467483
prev_expt = self._exp_type
468484
self._exp_type = None
@@ -475,15 +491,7 @@ def _visit_assign_with_receiver(self, node):
475491
self._types)
476492
if receiver_t is None:
477493
return
478-
type_var_map = {}
479-
# If the receiver type is parameterized, compute type variable
480-
# assignments
481-
if receiver_t.is_parameterized():
482-
type_var_map = receiver_t.get_type_variable_assignments()
483-
# If the type of receiver is a type variable, get its bound.
484-
if receiver_t.is_type_var():
485-
receiver_t = receiver_t.get_bound_rec(self._bt_factory)
486-
494+
receiver_t, type_var_map = self._get_receiver_type(receiver_t)
487495
f = tu.get_decl_from_inheritance(receiver_t, node.name, self._context)
488496
assert f is not None, (
489497
"Field " + node.name + " was not found in class " +
@@ -762,6 +770,13 @@ def _infer_type_variable_by_ret(self, parent_id, node_id, ret_type,
762770
self._inferred_nodes[parent_id].append(
763771
TypeNode(ret_type, None))
764772
return
773+
if decl_ret_type.is_wildcard() and decl_ret_type.bound is not None:
774+
self._inferred_nodes[parent_id].append(
775+
TypeNode(ret_type.bound, None)
776+
)
777+
return
778+
if decl_ret_type.is_wildcard():
779+
return
765780
self._infer_type_variables_parameterized_by_ret(
766781
parent_id, node_id, decl_ret_type, func_type_parameters,
767782
type_var_nodes)
@@ -781,8 +796,7 @@ def visit_func_call(self, node):
781796
if receiver_t is None:
782797
return
783798

784-
if receiver_t.is_type_var():
785-
receiver_t = receiver_t.get_bound_rec(self._bt_factory)
799+
receiver_t, _ = self._get_receiver_type(receiver_t)
786800
fun_decl = tu.get_decl_from_inheritance(receiver_t,
787801
node.func, self._context)
788802
if fun_decl is None:

0 commit comments

Comments
 (0)