# Path: supplement/fixer.py
# def try_to_fix(error, code):
#     if type(error) == SyntaxError:
#         before, line, after = get_lines(code, error.lineno)
# 
#         if error.text[:error.offset-1].rstrip().endswith('.'):
#             return (replace_line(before, error.text[:error.offset-1].rstrip() +
#                 '_someattr' + error.text[error.offset-1:], after),
#                 ('line-offset', error.lineno, len(error.text[:error.offset-1].rstrip())))
# 
#         if error.text.rstrip().endswith('if'):
#             return (replace_line(before, line.rstrip() + ' _somevar: pass', after),
#                 ('end-of-line', error.lineno))
# 
#         lines = code.splitlines()
#         result = find_unclosed_try(lines, error.lineno)
#         if result:
#             return unwrap_block(result[0], result[1], lines), ('end-of-line', result[1] + 1)
# 
#         if any(map(error.text.lstrip().startswith, ('with', 'for', 'if', 'while', 'except'))) \
#                 and error.text[-1] != ':':
# 
#             loc = 'end-of-line', error.lineno
# 
#             if any(map(error.text.rstrip().endswith, ('with', ' in', 'while'))):
#                 return replace_line(before, line.rstrip() + ' _somevar: pass', after), loc
# 
#             return replace_line(before, line.rstrip() + ': pass', after), loc
# 
#         if lines[-1].strip() and error.lineno == len(lines):
#             return remove_block(error.lineno-1, error.lineno, lines), ('end-of-file',)
# 
#         result = find_prev_block_start(lines, error.lineno)
#         if result is not None:
#             return remove_block(result, error.lineno-2, lines), ('end-of-line', result+1)
# 
#     elif type(error) == IndentationError:
#         before, line, after = get_lines(code, error.lineno)
#         for i, l in renumerate(before):
#             sline = l.strip()
#             if sline:
#                 if sline == 'try:':
#                     return replace_lineno(code.splitlines(), i, ''), ('end-of-line', error.lineno - 1)
#                 if sline[-1] == ':':
#                     return append_before('pass', i, before, line, after), ('end-of-line', error.lineno - 1)
# 
#     return code, None
# 
# def sanitize_encoding(source):
#     if isinstance(source, unicode):
#         parts = source.split(u'\n', 4)
#         for i in range(min(3, len(parts))):
#             parts[i] = parts[i].replace(u'coding=', u'codang=').replace(u'coding:', u'codang:')
# 
#         return u'\n'.join(parts)
#     else:
#         return source


from bisect import bisect_left as bisect
from ast import NodeVisitor, Load, parse, Name as AstName, dump
from tokenize import NL, NEWLINE, ERRORTOKEN, INDENT, DEDENT, generate_tokens, TokenError, NAME
from keyword import iskeyword
from contextlib import contextmanager
from itertools import chain
from .fixer import try_to_fix, sanitize_encoding


def check_syntax(source):
    source = sanitize_encoding(source)
    try:
        parse(source)
    except Exception, e:
        _, fixed_location = try_to_fix(e, source)
        if fixed_location:
            return fixed_location, e.msg
        else:
            return ('end-of-line', e.lineno), e.msg
    else:
        return None

def lint(source):

# Path: supplement/fixer.py
# def try_to_fix(error, code):
#     if type(error) == SyntaxError:
#         before, line, after = get_lines(code, error.lineno)
# 
#         if error.text[:error.offset-1].rstrip().endswith('.'):
#             return (replace_line(before, error.text[:error.offset-1].rstrip() +
#                 '_someattr' + error.text[error.offset-1:], after),
#                 ('line-offset', error.lineno, len(error.text[:error.offset-1].rstrip())))
# 
#         if error.text.rstrip().endswith('if'):
#             return (replace_line(before, line.rstrip() + ' _somevar: pass', after),
#                 ('end-of-line', error.lineno))
# 
#         lines = code.splitlines()
#         result = find_unclosed_try(lines, error.lineno)
#         if result:
#             return unwrap_block(result[0], result[1], lines), ('end-of-line', result[1] + 1)
# 
#         if any(map(error.text.lstrip().startswith, ('with', 'for', 'if', 'while', 'except'))) \
#                 and error.text[-1] != ':':
# 
#             loc = 'end-of-line', error.lineno
# 
#             if any(map(error.text.rstrip().endswith, ('with', ' in', 'while'))):
#                 return replace_line(before, line.rstrip() + ' _somevar: pass', after), loc
# 
#             return replace_line(before, line.rstrip() + ': pass', after), loc
# 
#         if lines[-1].strip() and error.lineno == len(lines):
#             return remove_block(error.lineno-1, error.lineno, lines), ('end-of-file',)
# 
#         result = find_prev_block_start(lines, error.lineno)
#         if result is not None:
#             return remove_block(result, error.lineno-2, lines), ('end-of-line', result+1)
# 
#     elif type(error) == IndentationError:
#         before, line, after = get_lines(code, error.lineno)
#         for i, l in renumerate(before):
#             sline = l.strip()
#             if sline:
#                 if sline == 'try:':
#                     return replace_lineno(code.splitlines(), i, ''), ('end-of-line', error.lineno - 1)
#                 if sline[-1] == ':':
#                     return append_before('pass', i, before, line, after), ('end-of-line', error.lineno - 1)
# 
#     return code, None
# 
# def sanitize_encoding(source):
#     if isinstance(source, unicode):
#         parts = source.split(u'\n', 4)
#         for i in range(min(3, len(parts))):
#             parts[i] = parts[i].replace(u'coding=', u'codang=').replace(u'coding:', u'codang:')
# 
#         return u'\n'.join(parts)
#     else:
#         return source


# Path: supplement/linter.py
from bisect import bisect_left as bisect
from ast import NodeVisitor, Load, parse, Name as AstName, dump
from tokenize import NL, NEWLINE, ERRORTOKEN, INDENT, DEDENT, generate_tokens, TokenError, NAME
from keyword import iskeyword
from contextlib import contextmanager
from itertools import chain
from .fixer import try_to_fix, sanitize_encoding



def check_syntax(source):
    source = sanitize_encoding(source)
    try:
        parse(source)
    except Exception, e:
        _, fixed_location = try_to_fix(e, source)
        if fixed_location:
            return fixed_location, e.msg
        else:
            return ('end-of-line', e.lineno), e.msg
    else:
        return None

def lint(source):

    source = sanitize_encoding(source)