예제 #1
0
def names_in_function_are_not_declared_in_outer_scope():
    node = nodes.func("f", nodes.arguments([]), [
        nodes.assign([nodes.ref("x")], nodes.none())
    ], type=None)
    
    declarations = find_declarations(node)
    assert not declarations.is_declared("x")
예제 #2
0
def can_infer_type_of_function_with_explicit_signature_of_aliased_function_type():
    args = nodes.arguments([])
    node = nodes.func("f", args=args, body=[], type=nodes.ref("Action"))
    type_bindings = {
        "Action": types.meta_type(types.func([], types.none_type))
    }
    assert_equal(types.func([], types.none_type), _infer_func_type(node, type_bindings))
예제 #3
0
def exception_handler_targets_cannot_be_accessed_from_nested_function():
    target_node = nodes.ref("error")
    ref_node = nodes.ref("error")
    body = [nodes.ret(ref_node)]
    func_node = nodes.func("f", nodes.arguments([]), body, type=None)
    try_node = nodes.try_(
        [],
        handlers=[
            nodes.except_(nodes.none(), target_node, [func_node])
        ],
    )
    
    declaration = name_declaration.ExceptionHandlerTargetNode("error")
    references = References([
        (target_node, declaration),
        (ref_node, declaration),
        (func_node, name_declaration.VariableDeclarationNode("f")),
    ])
    
    try:
        _updated_bindings(try_node, references=references)
        assert False, "Expected error"
    except errors.UnboundLocalError as error:
        assert_equal(ref_node, error.node)
        assert_is("error", error.name)
예제 #4
0
def type_parameters_of_function_are_definitely_bound():
    param = nodes.formal_type_parameter("T")
    arg_ref = nodes.ref("T")
    returns_ref = nodes.ref("T")
    explicit_type = nodes.signature(type_params=[param], args=[nodes.signature_arg(arg_ref)], returns=returns_ref)
    func_node = nodes.func("f", nodes.arguments([]), [], type=explicit_type)
    
    _updated_bindings(func_node)
예제 #5
0
def declarations_in_function_include_declarations_in_body():
    node = nodes.func("f", nodes.arguments([]), [
        nodes.assign([nodes.ref("x")], nodes.none())
    ], type=None)
    
    declarations = _declarations_in(node)
    assert isinstance(declarations.declaration("x"), name_declaration.VariableDeclarationNode)
    assert not declarations.is_declared("f")
예제 #6
0
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))
예제 #7
0
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))
예제 #8
0
def type_mismatch_if_return_type_is_incorrect():
    return_node = nodes.ret(nodes.str_literal("!"))
    node = nodes.func(
        "f",
        args=nodes.arguments([]),
        body=[return_node],
        type=nodes.signature(returns=nodes.ref("int")),
    )
    assert_type_mismatch(lambda: _infer_func_type(node), expected=types.int_type, actual=types.str_type, node=return_node)
예제 #9
0
def function_definitions_assignments_shadow_variables_of_same_name_in_outer_scope():
    args = nodes.arguments([])
    ref = nodes.ref("x")
    body = [nodes.assign([ref], nodes.none())]
    node = nodes.func("f", args, body, type=None)
    
    declarations = _create_declarations(["x", "f"])
    
    references = resolve(node, declarations)
    assert_is_not(declarations.declaration("x"), references.referenced_declaration(ref))
예제 #10
0
def cannot_declare_name_with_two_different_declaration_types():
    try:
        declarations = _declarations_in(nodes.module([
            nodes.assign([nodes.ref("f")], nodes.none()),
            nodes.func("f", nodes.arguments([]), [], type=None)
        ]))
        declarations = find_declarations(node)
        assert False, "Expected error"
    except errors.InvalidReassignmentError as error:
        assert_equal("function declaration and variable assignment cannot share the same name", str(error))
예제 #11
0
def names_in_function_signature_are_not_declared_in_outer_scope():
    explicit_type = nodes.signature(
        type_params=[nodes.formal_type_parameter("T")],
        args=[],
        returns=nodes.ref("T"),
    )
    node = nodes.func("f", nodes.arguments([]), [], type=explicit_type)
    
    declarations = find_declarations(node)
    assert not declarations.is_declared("T")
예제 #12
0
def function_definitions_bodies_can_access_variables_from_outer_scope():
    args = nodes.arguments([])
    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(declarations.declaration("x"), references.referenced_declaration(ref))
예제 #13
0
def can_infer_type_of_function_with_no_args_and_return_annotation():
    node = nodes.func(
        "f",
        args=nodes.arguments([]),
        body=[
            nodes.ret(nodes.int_literal(4))
        ],
        type=nodes.signature(returns=nodes.ref("int")),
    )
    assert_equal(types.func([], types.int_type), _infer_func_type(node))
예제 #14
0
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))
예제 #15
0
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]))
예제 #16
0
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))
예제 #17
0
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))
예제 #18
0
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))
예제 #19
0
def type_error_if_return_is_missing():
    node = nodes.func(
        "f",
        args=nodes.arguments([]),
        body=[],
        type=nodes.signature(returns=nodes.ref("int")),
    )
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.MissingReturnError as error:
        assert_equal(node, error.node)
        assert_equal("Function must return value of type 'int'", str(error))
예제 #20
0
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))
예제 #21
0
def function_definition_signature_has_names_resolved():
    int_ref = nodes.ref("int")
    str_ref = nodes.ref("str")
    
    signature = nodes.signature(
        args=[nodes.signature_arg(int_ref)],
        returns=str_ref,
    )
    node = nodes.func("f", nodes.arguments([]), [], type=signature)
    
    declarations = _create_declarations(["f", "int", "str"])
    references = resolve(node, declarations)
    assert_is(declarations.declaration("int"), references.referenced_declaration(int_ref))
    assert_is(declarations.declaration("str"), references.referenced_declaration(str_ref))
예제 #22
0
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)
예제 #23
0
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)
    )
예제 #24
0
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)
    )
예제 #25
0
def generic_function_definition_signature_has_names_resolved():
    param = nodes.formal_type_parameter("T")
    arg_ref = nodes.ref("T")
    return_ref = nodes.ref("T")
    
    signature = nodes.signature(
        type_params=[param],
        args=[nodes.signature_arg(arg_ref)],
        returns=return_ref,
    )
    node = nodes.func("f", nodes.arguments([]), [], type=signature)
    
    declarations = _create_declarations(["f"])
    references = resolve(node, declarations)
    assert not declarations.is_declared("T")
    assert_is(references.referenced_declaration(param), references.referenced_declaration(arg_ref))
    assert_is(references.referenced_declaration(param), references.referenced_declaration(return_ref))
예제 #26
0
def body_of_function_is_checked():
    _assert_child_statement_is_checked(lambda generate:
        generate.func("f", nodes.arguments([]), [generate.unbound_ref_statement()], type=None)
    )
예제 #27
0
def function_definitions_adds_function_name_to_context():
    node = nodes.func("f", nodes.arguments([]), [], type=None)
    
    declarations = _create_declarations(["f"])
    references = resolve(node, declarations)
    assert_is(declarations.declaration("f"), references.referenced_declaration(node))
예제 #28
0
def function_name_is_definitely_bound_after_function_definition():
    node = nodes.func("f", nodes.arguments([]), [], type=None)
    
    bindings = _updated_bindings(node)
    assert_equal(True, bindings.is_definitely_bound(node))
예제 #29
0
def arguments_of_function_are_definitely_bound():
    arg = nodes.arg("x")
    arg_ref = nodes.ref("x")
    func_node = nodes.func("f", nodes.arguments([arg]), [nodes.expression_statement(arg_ref)], type=None)
    
    _updated_bindings(func_node)
예제 #30
0
def variables_from_outer_scope_remain_bound():
    ref = nodes.ref("x")
    func_node = nodes.func("f", nodes.arguments([]), [nodes.expression_statement(ref)], type=None)
    
    _updated_bindings(func_node, is_definitely_bound={"x": True})