def can_infer_type_of_function_with_args_and_no_return(): signature = nodes.signature( args=[ nodes.signature_arg(nodes.ref("int")), nodes.signature_arg(nodes.ref("str")), ], returns=nodes.ref("none"), ) args = nodes.arguments([ nodes.argument("x"), nodes.argument("y"), ]) node = nodes.func("f", args=args, body=[], type=signature) assert_equal(types.func([types.int_type, types.str_type], types.none_type), _infer_func_type(node))
def error_if_type_signature_is_missing_from_function_with_args(): args = nodes.arguments([nodes.argument("x")]) body = [nodes.ret(nodes.ref("x"))] node = nodes.func("f", args, body, type=None) try: _infer_func_type(node) assert False, "Expected error" except errors.ArgumentsError as error: assert_equal("signature is missing from function definition", str(error))
def function_adds_arguments_to_context(): signature = nodes.signature( args=[nodes.signature_arg(nodes.ref("int"))], returns=nodes.ref("int") ) args = nodes.arguments([nodes.argument("x")]) body = [nodes.ret(nodes.ref("x"))] node = nodes.func("f", args, body, type=signature) assert_equal(types.func([types.int_type], types.int_type), _infer_func_type(node))
def function_definitions_adds_argument_names_to_body_context(): arg = nodes.argument("x") args = nodes.arguments([arg]) ref = nodes.ref("x") body = [nodes.ret(ref)] node = nodes.func("f", args, body, type=None) declarations = _create_declarations(["f"]) references = resolve(node, declarations) assert not declarations.is_declared("x") assert_is(references.referenced_declaration(arg), references.referenced_declaration(ref))
def function_definitions_arguments_shadow_variables_of_same_name_in_outer_scope(): arg = nodes.argument("x") args = nodes.arguments([arg]) ref = nodes.ref("x") body = [nodes.ret(ref)] node = nodes.func("f", args, body, type=None) declarations = _create_declarations(["x", "f"]) references = resolve(node, declarations) assert_is(references.referenced_declaration(arg), references.referenced_declaration(ref)) assert_is_not(declarations.declaration("x"), references.referenced_declaration(ref))
def error_if_type_signature_argument_is_optional_but_def_argument_is_not_optional(): signature = nodes.signature( args=[nodes.signature_arg(nodes.ref("int"), optional=True)], returns=nodes.type_union([nodes.ref("int"), nodes.ref("none")]) ) args = nodes.arguments([nodes.argument("x")]) body = [nodes.ret(nodes.ref("x"))] node = nodes.func("f", args, body, type=signature) try: _infer_func_type(node) assert False, "Expected error" except errors.ArgumentsError as error: assert_equal("optional argument 'x' must have default value", str(error))
def error_if_type_signature_has_different_number_of_args_from_def(): signature = nodes.signature( args=[nodes.signature_arg(nodes.ref("int")), nodes.signature_arg(nodes.ref("int"))], returns=nodes.ref("int") ) args = nodes.arguments([nodes.argument("x")]) body = [nodes.ret(nodes.ref("x"))] node = nodes.func("f", args, body, type=signature) try: _infer_func_type(node) assert False, "Expected error" except errors.ArgumentsError as error: assert_equal("args length mismatch: def has 1, signature has 2", str(error))
def error_if_name_of_argument_does_not_match_name_in_signature(): signature = nodes.signature( args=[nodes.signature_arg("y", nodes.ref("int"))], returns=nodes.ref("int") ) args = nodes.arguments([nodes.argument("x")]) body = [nodes.ret(nodes.ref("x"))] node = nodes.func("f", args, body, type=signature) try: _infer_func_type(node) assert False, "Expected error" except errors.ArgumentsError as error: assert_equal("argument 'x' has name 'y' in signature", str(error))
def can_type_check_generic_function_with_type_parameters(): signature = nodes.signature( type_params=[nodes.formal_type_parameter("T")], args=[ nodes.signature_arg(nodes.ref("T")), ], returns=nodes.ref("T"), ) args = nodes.arguments([ nodes.argument("value"), ]) node = nodes.func("f", args=args, body=[nodes.ret(nodes.ref("value"))], type=signature) assert_equal(types.func([types.int_type], types.int_type), _infer_func_type(node).instantiate([types.int_type]))
def argument_type_in_signature_is_unioned_with_none_if_argument_is_optional(): signature = nodes.signature( args=[nodes.signature_arg(nodes.ref("int"))], returns=nodes.ref("int") ) args = nodes.arguments([nodes.argument("x", optional=True)]) body = [nodes.ret(nodes.ref("x"))] node = nodes.func("f", args, body, type=signature) try: _infer_func_type(node) assert False, "Expected error" except errors.UnexpectedValueTypeError as error: assert_equal(types.int_type, error.expected) assert_equal(types.union(types.int_type, types.none_type), error.actual)
def can_infer_type_of_function_with_optional_arg(): signature = nodes.signature( args=[ nodes.signature_arg(nodes.ref("int"), optional=True), ], returns=nodes.ref("none") ) args = nodes.arguments([ nodes.argument("x", optional=True), ]) node = nodes.func("f", args=args, body=[], type=signature) assert_equal( types.func([types.func_arg(None, types.int_type, optional=True)], types.none_type), _infer_func_type(node) )
def can_infer_type_of_function_with_named_arg(): signature = nodes.signature( args=[ nodes.signature_arg("message", nodes.ref("int")), ], returns=nodes.ref("none") ) args = nodes.arguments([ nodes.argument("message"), ]) node = nodes.func("f", args=args, body=[], type=signature) assert_equal( types.func([types.func_arg("message", types.int_type)], types.none_type), _infer_func_type(node) )