# keyword_args ExprNode or None Dict of keyword arguments
type = py_object_type
- is_simple_call = False
subexprs = ['function', 'positional_args', 'keyword_args']
self.type = error_type
return self
if hasattr(self.function, 'entry'):
- self.map_keywords_to_posargs()
- if not self.is_simple_call:
+ node = self.map_keywords_to_posargs(env)
+ if node is not None:
+ return node.analyse_types(env)
+ else:
if self.function.entry.as_variable:
self.function = self.function.coerce_to_pyobject(env)
else:
self.is_temp = 1
return self
- def map_keywords_to_posargs(self):
+ def map_keywords_to_posargs(self, env):
if not isinstance(self.positional_args, TupleNode):
# has starred argument
- return
+ return None
if not isinstance(self.keyword_args, DictNode):
# nothing to do here
- return
+ return None
function = self.function
entry = getattr(function, 'entry', None)
if not entry or not entry.is_cfunction:
- return
+ return None
args = self.positional_args.args
kwargs = self.keyword_args
# will lead to an error elsewhere
error(self.pos, "function call got too many positional arguments, "
"expected %d, got %s" % (len(declared_args), len(args)))
- return
+ return None
matched_pos_args = set([arg.name for arg in declared_args[:len(args)]])
unmatched_args = declared_args[len(args):]
name = arg.key.value
if name in matched_pos_args:
error(arg.pos, "keyword argument '%s' passed twice" % name)
- return
+ return None
if decl_arg.name == name:
matched_kwargs.add(name)
args.append(arg.value)
# into ordered temps if necessary
if not matched_kwargs:
- return
+ return None
self.positional_args.args = args
if len(kwargs.key_value_pairs) == len(matched_kwargs):
- self.keyword_args = None
- self.is_simple_call = True
- else:
- kwargs.key_value_pairs = [
- item for item in kwargs.key_value_pairs
- if item.key.value not in matched_kwargs ]
+ # all keywords mapped => only positional arguments left
+ return SimpleCallNode(
+ self.pos, function=function, args=args)
+
+ kwargs.key_value_pairs = [
+ item for item in kwargs.key_value_pairs
+ if item.key.value not in matched_kwargs ]
+ return None
def generate_result_code(self, code):
if self.type.is_error: return
return (base.name, index_val)
-class SimplifyCalls(Visitor.EnvTransform):
- """
- Replace GeneralCallNode by SimpleCallNode if possible.
- """
- def visit_GeneralCallNode(self, node):
- self.visitchildren(node)
- if not node.is_simple_call:
- return node
- args = [ unwrap_coerced_node(arg)
- for arg in node.positional_args.args ]
- call_node = ExprNodes.SimpleCallNode(
- node.pos,
- function=node.function,
- args=args)
- call_node = call_node.analyse_types(self.current_env())
- if node.type != call_node.type:
- call_node = call_node.coerce_to(
- node.type, self.current_env())
- return call_node
-
-
class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
"""Optimize some common calls to builtin types *before* the type
analysis phase and *after* the declarations analysis phase.
from AutoDocTransforms import EmbedSignature
from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform
from Optimize import EarlyReplaceBuiltinCalls, OptimizeBuiltinCalls
- from Optimize import InlineDefNodeCalls, SimplifyCalls
+ from Optimize import InlineDefNodeCalls
from Optimize import ConstantFolding, FinalOptimizePhase
from Optimize import DropRefcountingTransform
from Optimize import ConsolidateOverflowCheck
_check_c_declarations,
InlineDefNodeCalls(context),
AnalyseExpressionsTransform(context),
- SimplifyCalls(context),
FindInvalidUseOfFusedTypes(context),
CreateClosureClasses(context), ## After all lookups and type inference
ExpandInplaceOperators(context),