def parse_fragment(lexer: Lexer) -> Union[FragmentSpreadNode, InlineFragmentNode]:
    """Corresponds to both FragmentSpread and InlineFragment in the spec.

    FragmentSpread: ... FragmentName Directives?
    InlineFragment: ... TypeCondition? Directives? SelectionSet
    """
    start = lexer.token
    expect_token(lexer, TokenKind.SPREAD)

    has_type_condition = expect_optional_keyword(lexer, "on")
    if not has_type_condition and peek(lexer, TokenKind.NAME):
        return FragmentSpreadNode(
            name=parse_fragment_name(lexer),
            directives=parse_directives(lexer, False),
            loc=loc(lexer, start),
        )
    return InlineFragmentNode(
        type_condition=parse_named_type(lexer) if has_type_condition else None,
        directives=parse_directives(lexer, False),
        selection_set=parse_selection_set(lexer),
        loc=loc(lexer, start),
    )
Corresponds to both FragmentSpread and InlineFragment in the spec.

    FragmentSpread: ... FragmentName Directives?
    InlineFragment: ... TypeCondition? Directives? SelectionSet