<s> import os <EOL> import os . path <EOL> import sys <EOL> import socket <EOL> import sublime <EOL> import sublime_plugin <EOL> import subprocess <EOL> import threading <EOL> import json <EOL> import time <EOL> import re <EOL> from functools import reduce <EOL> if int ( sublime . version ( ) ) < <NUM_LIT> : <EOL> import symbols <EOL> from sublime_haskell_common import * <EOL> else : <EOL> import SublimeHaskell . symbols as symbols <EOL> from SublimeHaskell . sublime_haskell_common import * <EOL> def concat_args ( args ) : <EOL> def cat ( x , y ) : <EOL> ( px , ex ) = x <EOL> ( py , ey ) = y <EOL> return ( px or py , ( ex if px else [ ] ) + ( ey if py else [ ] ) ) <EOL> return reduce ( cat , args , ( True , [ ] ) ) [ <NUM_LIT:1> ] <EOL> def concat_opts ( opts ) : <EOL> def cat ( x , y ) : <EOL> ( px , ex ) = x <EOL> ( py , ey ) = y <EOL> v = ( ex if px else { } ) . copy ( ) <EOL> v . update ( ( ey if py else { } ) . copy ( ) ) <EOL> return ( px or py , v ) <EOL> return reduce ( cat , opts , ( True , { } ) ) [ <NUM_LIT:1> ] <EOL> def flatten_opts ( opts ) : <EOL> r = [ ] <EOL> def to_opt ( x ) : <EOL> return '<STR_LIT>' . format ( x ) <EOL> for k , v in opts . items ( ) : <EOL> if v is None : <EOL> r . append ( to_opt ( k ) ) <EOL> elif type ( v ) is list : <EOL> for n in v : <EOL> r . extend ( [ to_opt ( k ) , str ( n ) ] ) <EOL> else : <EOL> r . extend ( [ to_opt ( k ) , str ( v ) ] ) <EOL> return r <EOL> def hsdev_enabled ( ) : <EOL> return get_setting_async ( '<STR_LIT>' ) == True <EOL> def hsdev_enable ( enable = True ) : <EOL> set_setting_async ( '<STR_LIT>' , enable ) <EOL> def hsdev_version ( ) : <EOL> try : <EOL> ( exit_code , out , err ) = call_and_wait ( [ '<STR_LIT>' , '<STR_LIT:version>' ] ) <EOL> if exit_code == <NUM_LIT:0> : <EOL> m = re . match ( '<STR_LIT>' , out ) <EOL> if m : <EOL> major = int ( m . group ( '<STR_LIT>' ) ) <EOL> minor = int ( m . group ( '<STR_LIT>' ) ) <EOL> revision = int ( m . group ( '<STR_LIT>' ) ) <EOL> build = int ( m . group ( '<STR_LIT>' ) ) <EOL> return [ major , minor , revision , build ] <EOL> except FileNotFoundError : <EOL> pass <EOL> return None <EOL> def show_version ( ver ) : <EOL> return '<STR_LIT:.>' . join ( map ( lambda i : str ( i ) , ver ) ) <EOL> def check_version ( ver , minimal = [ <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ] , maximal = None ) : <EOL> if ver is None : <EOL> return False <EOL> if ver < minimal : <EOL> return False <EOL> if maximal and ver >= maximal : <EOL> return False <EOL> return True <EOL> def if_some ( x , lst ) : <EOL> return lst if x is not None else [ ] <EOL> def cabal_path ( cabal ) : <EOL> if not cabal : <EOL> return [ ] <EOL> return [ "<STR_LIT>" ] if cabal == '<STR_LIT>' else [ "<STR_LIT>" . format ( cabal ) ] <EOL> def hsinspect ( module = None , file = None , cabal = None , ghc_opts = [ ] ) : <EOL> cmd = [ '<STR_LIT>' ] <EOL> on_result = lambda s : s <EOL> if module : <EOL> cmd . extend ( [ module ] ) <EOL> on_result = parse_module <EOL> elif file : <EOL> cmd . extend ( [ file ] ) <EOL> on_result = parse_module <EOL> elif cabal : <EOL> cmd . extend ( [ cabal ] ) <EOL> else : <EOL> log ( '<STR_LIT>' , log_debug ) <EOL> return None <EOL> for opt in ghc_opts : <EOL> cmd . extend ( [ '<STR_LIT>' , opt ] ) <EOL> r = call_and_wait_tool ( cmd , '<STR_LIT>' , lambda s : json . loads ( s ) , file , None ) <EOL> if r : <EOL> if '<STR_LIT:error>' in r : <EOL> log ( '<STR_LIT>' . format ( r [ '<STR_LIT:error>' ] ) , log_error ) <EOL> else : <EOL> return on_result ( r ) <EOL> return None <EOL> def print_status ( s ) : <EOL> print ( s [ '<STR_LIT:status>' ] ) <EOL> def parse_database ( s ) : <EOL> if not s : <EOL> return None <EOL> if s and '<STR_LIT>' in s and '<STR_LIT>' in s : <EOL> return ( s [ '<STR_LIT>' ] , [ parse_module ( m ) for m in s [ '<STR_LIT>' ] ] ) <EOL> return None <EOL> def parse_decls ( s ) : <EOL> if s is None : <EOL> return None <EOL> return [ parse_module_declaration ( decl ) for decl in s ] <EOL> def parse_modules_brief ( s ) : <EOL> if s is None : <EOL> return None <EOL> return [ parse_module_id ( m ) for m in s ] <EOL> def get_value ( dc , ks , defval = None ) : <EOL> if dc is None : <EOL> return defval <EOL> if type ( ks ) == list : <EOL> cur = dc <EOL> for k in ks : <EOL> cur = cur . get ( k ) <EOL> if cur is None : <EOL> return defval <EOL> return cur <EOL> else : <EOL> return dc . get ( ks , defval ) <EOL> def parse_package_db ( d , defval = None ) : <EOL> if type ( d ) == dict : <EOL> pdb = get_value ( d , '<STR_LIT>' ) <EOL> return symbols . PackageDb ( package_db = pdb ) if pdb else defval <EOL> if d == '<STR_LIT>' : <EOL> return symbols . PackageDb ( global_db = True ) <EOL> if d == '<STR_LIT>' : <EOL> return symbols . PackageDb ( user_db = True ) <EOL> return defval <EOL> def parse_position ( d ) : <EOL> if not d : <EOL> return None <EOL> line = get_value ( d , '<STR_LIT>' ) <EOL> column = get_value ( d , '<STR_LIT>' ) <EOL> if line is not None and column is not None : <EOL> return symbols . Position ( line , column ) <EOL> return None <EOL> def parse_location ( d ) : <EOL> loc = symbols . Location ( <EOL> get_value ( d , '<STR_LIT:file>' ) , <EOL> get_value ( d , '<STR_LIT>' ) ) <EOL> if not loc . is_null ( ) : <EOL> return loc <EOL> loc = symbols . InstalledLocation ( <EOL> symbols . parse_package ( get_value ( d , '<STR_LIT>' ) ) , <EOL> parse_package_db ( get_value ( d , '<STR_LIT>' ) ) ) <EOL> if not loc . is_null ( ) : <EOL> return loc <EOL> loc = symbols . OtherLocation ( <EOL> get_value ( d , '<STR_LIT:source>' ) ) <EOL> if not loc . is_null ( ) : <EOL> return loc <EOL> return None <EOL> def parse_import ( d ) : <EOL> if not d : <EOL> return None <EOL> return symbols . Import ( d [ '<STR_LIT:name>' ] , d [ '<STR_LIT>' ] , d . get ( '<STR_LIT>' ) , parse_position ( d . get ( '<STR_LIT>' ) ) ) <EOL> def parse_module_id ( d ) : <EOL> if d is None : <EOL> return None <EOL> return symbols . Module ( <EOL> d [ '<STR_LIT:name>' ] , <EOL> [ ] , [ ] , { } , <EOL> parse_location ( d . get ( '<STR_LIT:location>' ) ) ) <EOL> def parse_declaration ( decl ) : <EOL> try : <EOL> what = decl [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> docs = crlf2lf ( decl . get ( '<STR_LIT>' ) ) <EOL> name = decl [ '<STR_LIT:name>' ] <EOL> pos = parse_position ( decl . get ( '<STR_LIT>' ) ) <EOL> imported = [ ] <EOL> if '<STR_LIT>' in decl and decl [ '<STR_LIT>' ] : <EOL> imported = [ parse_import ( d ) for d in decl [ '<STR_LIT>' ] ] <EOL> defined = None <EOL> if '<STR_LIT>' in decl and decl [ '<STR_LIT>' ] : <EOL> defined = parse_module_id ( decl [ '<STR_LIT>' ] ) <EOL> if what == '<STR_LIT>' : <EOL> return symbols . Function ( name , decl [ '<STR_LIT>' ] . get ( '<STR_LIT:type>' ) , docs , imported , defined , pos ) <EOL> elif what == '<STR_LIT:type>' : <EOL> return symbols . Type ( name , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT:args>' , [ ] ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , docs , imported , defined , pos ) <EOL> elif what == '<STR_LIT>' : <EOL> return symbols . Newtype ( name , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT:args>' , [ ] ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , docs , imported , defined , pos ) <EOL> elif what == '<STR_LIT:data>' : <EOL> return symbols . Data ( name , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT:args>' , [ ] ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , docs , imported , defined , pos ) <EOL> elif what == '<STR_LIT:class>' : <EOL> return symbols . Class ( name , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT:args>' , [ ] ) , decl [ '<STR_LIT>' ] [ '<STR_LIT:info>' ] . get ( '<STR_LIT>' ) , docs , imported , defined , pos ) <EOL> else : <EOL> return None <EOL> except Exception as e : <EOL> log ( '<STR_LIT>' . format ( e ) , log_error ) <EOL> return None <EOL> def parse_declarations ( decls ) : <EOL> if decls is None : <EOL> return None <EOL> return [ parse_declaration ( d ) for d in decls ] <EOL> def parse_module_declaration ( d , parse_module_info = True ) : <EOL> try : <EOL> m = None <EOL> if '<STR_LIT>' in d and parse_module_info : <EOL> m = parse_module_id ( d [ '<STR_LIT>' ] ) <EOL> loc = parse_location ( d [ '<STR_LIT>' ] . get ( '<STR_LIT:location>' ) ) <EOL> decl = parse_declaration ( d [ '<STR_LIT>' ] ) <EOL> if not decl : <EOL> return None <EOL> decl . module = m <EOL> return decl <EOL> except : <EOL> return None <EOL> def parse_module ( d ) : <EOL> if d is None : <EOL> return None <EOL> return symbols . Module ( <EOL> d [ '<STR_LIT:name>' ] , <EOL> d . get ( '<STR_LIT>' ) , <EOL> [ parse_import ( i ) for i in d [ '<STR_LIT>' ] ] if '<STR_LIT>' in d else [ ] , <EOL> dict ( ( decl [ '<STR_LIT:name>' ] , parse_declaration ( decl ) ) for decl in d [ '<STR_LIT>' ] ) if '<STR_LIT>' in d else { } , <EOL> parse_location ( d . get ( '<STR_LIT:location>' ) ) ) <EOL> def parse_modules ( ds ) : <EOL> if ds is None : <EOL> return None <EOL> return [ parse_module ( d ) for d in ds ] <EOL> def parse_cabal_package ( d ) : <EOL> if d is None : <EOL> return None <EOL> return symbols . CabalPackage ( <EOL> d [ '<STR_LIT:name>' ] , <EOL> d . get ( '<STR_LIT>' ) , <EOL> d . get ( '<STR_LIT>' ) , <EOL> d . get ( '<STR_LIT>' ) , <EOL> d . get ( '<STR_LIT>' ) , <EOL> d . get ( '<STR_LIT>' ) ) <EOL> def parse_corrections ( d ) : <EOL> if d is None : <EOL> return None <EOL> return [ parse_correction ( c ) for c in d ] <EOL> def parse_correction ( d ) : <EOL> return symbols . Correction ( <EOL> d [ '<STR_LIT:source>' ] [ '<STR_LIT:file>' ] , <EOL> d [ '<STR_LIT>' ] , <EOL> d [ '<STR_LIT>' ] [ '<STR_LIT:message>' ] , <EOL> parse_corrector ( d [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> def parse_corrector ( d ) : <EOL> return symbols . Corrector ( <EOL> parse_position ( d [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) , <EOL> parse_position ( d [ '<STR_LIT>' ] [ '<STR_LIT:to>' ] ) , <EOL> d [ '<STR_LIT>' ] ) <EOL> def encode_corrections ( cs ) : <EOL> return [ encode_correction ( c ) for c in cs ] <EOL> def encode_correction ( c ) : <EOL> return { <EOL> '<STR_LIT:source>' : { <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT:file>' : c . file } , <EOL> '<STR_LIT>' : c . level , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : encode_corrector ( c . corrector ) , <EOL> '<STR_LIT:message>' : c . message } , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : encode_position ( c . corrector . start . from_zero_based ( ) ) , <EOL> '<STR_LIT:to>' : encode_position ( c . corrector . end . from_zero_based ( ) ) } <EOL> } <EOL> def encode_corrector ( c ) : <EOL> return { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : encode_position ( c . start ) , <EOL> '<STR_LIT:to>' : encode_position ( c . end ) } , <EOL> '<STR_LIT>' : c . contents } <EOL> def encode_position ( p ) : <EOL> return { <EOL> '<STR_LIT>' : p . line , <EOL> '<STR_LIT>' : p . column } <EOL> def encode_package_db ( db ) : <EOL> if db . user_db : <EOL> return '<STR_LIT>' <EOL> if db . global_db : <EOL> return '<STR_LIT>' <EOL> if db . package_db : <EOL> return { '<STR_LIT>' : db . package_db } <EOL> return None <EOL> def reconnect_function ( fn ) : <EOL> def wrapped ( self , * args , ** kwargs ) : <EOL> autoconnect_ = kwargs . pop ( '<STR_LIT>' , False ) <EOL> on_reconnect_ = kwargs . pop ( '<STR_LIT>' , None ) <EOL> just_connect_ = kwargs . pop ( '<STR_LIT>' , False ) <EOL> def run_fn ( ) : <EOL> if not just_connect_ : <EOL> self . autoconnect = autoconnect_ <EOL> self . on_reconnect = on_reconnect_ <EOL> return fn ( self , * args , ** kwargs ) <EOL> if not just_connect_ : <EOL> self . set_reconnect_function ( run_fn ) <EOL> return run_fn ( ) <EOL> return wrapped <EOL> class begin_connecting ( object ) : <EOL> def __init__ ( self , agent ) : <EOL> self . agent = agent <EOL> def __enter__ ( self ) : <EOL> self . agent . set_connecting ( ) <EOL> return self <EOL> def __exit__ ( self , type , value , traceback ) : <EOL> if type : <EOL> self . agent . set_unconnected ( ) <EOL> else : <EOL> if self . agent . is_connecting ( ) : <EOL> self . agent . set_unconnected ( ) <EOL> def connect_function ( fn ) : <EOL> def wrapped ( self , * args , ** kwargs ) : <EOL> if self . is_unconnected ( ) : <EOL> with begin_connecting ( self ) : <EOL> return fn ( self , * args , ** kwargs ) <EOL> else : <EOL> log ( '<STR_LIT>' , log_warning ) <EOL> return wrapped <EOL> def hsdev_command ( async = False , timeout = None , is_list = False ) : <EOL> def wrap_function ( fn ) : <EOL> def wrapped ( self , * args , ** kwargs ) : <EOL> wait_flag = kwargs . pop ( '<STR_LIT>' , not async ) <EOL> timeout_arg = kwargs . pop ( '<STR_LIT>' , timeout ) <EOL> on_resp = kwargs . pop ( '<STR_LIT>' , None ) <EOL> on_not = kwargs . pop ( '<STR_LIT>' , None ) <EOL> on_err = kwargs . pop ( '<STR_LIT>' , None ) <EOL> on_res_part = kwargs . pop ( '<STR_LIT>' , None ) <EOL> split_res = kwargs . pop ( '<STR_LIT>' , on_res_part is not None ) <EOL> ( name_ , opts_ , on_result_ ) = fn ( self , * args , ** kwargs ) <EOL> if is_list and split_res : <EOL> result = [ ] <EOL> def on_notify ( n ) : <EOL> if '<STR_LIT>' in n : <EOL> rp = on_result_ ( [ n [ '<STR_LIT>' ] ] ) [ <NUM_LIT:0> ] <EOL> call_callback ( on_res_part , rp ) <EOL> result . append ( rp ) <EOL> else : <EOL> call_callback ( on_not , n ) <EOL> def on_response ( r ) : <EOL> on_resp ( result ) <EOL> opts_ . update ( { '<STR_LIT>' : None } ) <EOL> r = self . call ( <EOL> name_ , <EOL> opts_ , <EOL> on_response = on_response if on_resp else None , <EOL> on_notify = on_notify , <EOL> on_error = on_err , <EOL> wait = wait_flag , <EOL> timeout = timeout_arg ) <EOL> if wait_flag : <EOL> return result <EOL> return r <EOL> else : <EOL> def on_response ( r ) : <EOL> on_resp ( on_result_ ( r ) ) <EOL> r = self . call ( <EOL> name_ , <EOL> opts_ , <EOL> on_response = on_response if on_resp else None , <EOL> on_notify = on_not , <EOL> on_error = on_err , <EOL> wait = wait_flag , <EOL> timeout = timeout_arg ) <EOL> if wait_flag : <EOL> return on_result_ ( r ) <EOL> return r <EOL> return wrapped <EOL> return wrap_function <EOL> def command ( fn ) : <EOL> return hsdev_command ( async = False , timeout = <NUM_LIT:1> ) ( fn ) <EOL> def async_command ( fn ) : <EOL> return hsdev_command ( async = True ) ( fn ) <EOL> def list_command ( fn ) : <EOL> return hsdev_command ( async = False , timeout = <NUM_LIT:1> , is_list = True ) ( fn ) <EOL> def async_list_command ( fn ) : <EOL> return hsdev_command ( async = True , is_list = True ) ( fn ) <EOL> def cmd ( name_ , opts_ = { } , on_result = lambda r : r ) : <EOL> return ( name_ , opts_ , on_result ) <EOL> def call_callback ( fn , * args , ** kwargs ) : <EOL> name = kwargs . get ( '<STR_LIT:name>' ) <EOL> if name : <EOL> del kwargs [ '<STR_LIT:name>' ] <EOL> try : <EOL> if fn is not None : <EOL> fn ( * args , ** kwargs ) <EOL> except Exception as e : <EOL> log ( "<STR_LIT>" . format ( name or '<STR_LIT>' , e ) ) <EOL> def format_error_details ( ds ) : <EOL> return '<STR_LIT:U+002CU+0020>' . join ( [ '<STR_LIT>' . format ( k , v ) for k , v in ds . items ( ) ] ) <EOL> class HsDevCallbacks ( object ) : <EOL> def __init__ ( self , id , command , on_response = None , on_notify = None , on_error = None ) : <EOL> self . id = id <EOL> self . command = command <EOL> self . start_time = time . clock ( ) <EOL> self . on_response = on_response <EOL> self . on_notify = on_notify <EOL> self . on_error = on_error <EOL> def time ( self ) : <EOL> return time . clock ( ) - self . start_time if self . start_time is not None else None <EOL> def log_time ( self ) : <EOL> log ( '<STR_LIT>' . format ( self . command , self . time ( ) ) , log_trace ) <EOL> def call_response ( self , r ) : <EOL> self . log_time ( ) <EOL> call_callback ( self . on_response , r ) <EOL> def call_notify ( self , n ) : <EOL> call_callback ( self . on_notify , n ) <EOL> def call_error ( self , e , ds ) : <EOL> self . log_time ( ) <EOL> log ( '<STR_LIT>' . format ( self . command , e , format_error_details ( ds ) ) , log_error ) <EOL> call_callback ( self . on_error , e , ds ) <EOL> class HsDev ( object ) : <EOL> def __init__ ( self , port = <NUM_LIT> ) : <EOL> self . port = port <EOL> self . connecting = threading . Event ( ) <EOL> self . connected = threading . Event ( ) <EOL> self . socket = None <EOL> self . listener = None <EOL> self . hsdev_address = None <EOL> self . autoconnect = True <EOL> self . map = LockedObject ( { } ) <EOL> self . id = <NUM_LIT:1> <EOL> self . connect_fun = None <EOL> self . part = '<STR_LIT>' <EOL> self . on_connected = None <EOL> self . on_disconnected = None <EOL> self . on_reconnect = None <EOL> def __del__ ( self ) : <EOL> self . close ( ) <EOL> def set_reconnect_function ( self , f ) : <EOL> if self . connect_fun is None : <EOL> self . connect_fun = f <EOL> def reconnect ( self ) : <EOL> if self . connect_fun is not None : <EOL> log ( '<STR_LIT>' , log_info ) <EOL> call_callback ( self . on_reconnect , name = '<STR_LIT>' ) <EOL> self . connect_fun ( ) <EOL> else : <EOL> log ( '<STR_LIT>' ) <EOL> @ staticmethod <EOL> def run_server ( port = <NUM_LIT> , cache = None , log_file = None , log_config = None ) : <EOL> cmd = concat_args ( [ <EOL> ( True , [ "<STR_LIT>" , "<STR_LIT>" ] ) , <EOL> ( port , [ "<STR_LIT>" , str ( port ) ] ) , <EOL> ( cache , [ "<STR_LIT>" , cache ] ) , <EOL> ( log_file , [ "<STR_LIT>" , log_file ] ) , <EOL> ( log_config , [ "<STR_LIT>" , log_config ] ) ] ) <EOL> log ( '<STR_LIT>' , log_info ) <EOL> p = call_and_wait ( cmd , wait = False ) <EOL> if not p : <EOL> log ( '<STR_LIT>' , log_error ) <EOL> return None <EOL> while True : <EOL> output = crlf2lf ( decode_bytes ( p . stdout . readline ( ) ) ) <EOL> m = re . match ( r'<STR_LIT>' , output ) <EOL> if m : <EOL> log ( '<STR_LIT>' . format ( m . group ( '<STR_LIT:port>' ) ) ) <EOL> p . stdout . close ( ) <EOL> p . stderr . close ( ) <EOL> return p <EOL> @ staticmethod <EOL> def start_server ( port = <NUM_LIT> , cache = None , log_file = None , log_config = None ) : <EOL> cmd = concat_args ( [ <EOL> ( True , [ "<STR_LIT>" , "<STR_LIT:start>" ] ) , <EOL> ( port , [ "<STR_LIT>" , str ( port ) ] ) , <EOL> ( cache , [ "<STR_LIT>" , cache ] ) , <EOL> ( log_file , [ "<STR_LIT>" , log_file ] ) , <EOL> ( log_config , [ "<STR_LIT>" , log_config ] ) ] ) <EOL> def parse_response ( s ) : <EOL> try : <EOL> return { } if s . isspace ( ) else json . loads ( s ) <EOL> except Exception as e : <EOL> return { '<STR_LIT:error>' : '<STR_LIT>' , '<STR_LIT>' : s } <EOL> log ( '<STR_LIT>' , log_info ) <EOL> ret = call_and_wait_tool ( cmd , '<STR_LIT>' , '<STR_LIT>' , None , None , None , check_enabled = False ) <EOL> if ret is not None : <EOL> return ret <EOL> return None <EOL> @ staticmethod <EOL> def client ( port = <NUM_LIT> , cache = None , autoconnect = False ) : <EOL> start_server ( port = port , cache = cache ) <EOL> h = HsDev ( port = port ) <EOL> h . connect ( autoconnect = autoconnect ) <EOL> return h <EOL> @ staticmethod <EOL> def client_async ( port = <NUM_LIT> , cache = None , autoconnect = False ) : <EOL> start_server ( port = port , cache = cache ) <EOL> h = HsDev ( port = port ) <EOL> h . connect_async ( autoconnect = autoconnect ) <EOL> return h <EOL> @ connect_function <EOL> @ reconnect_function <EOL> def connect ( self , tries = <NUM_LIT:10> , delay = <NUM_LIT:1.0> ) : <EOL> self . socket = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> for n in range ( <NUM_LIT:0> , tries ) : <EOL> try : <EOL> log ( '<STR_LIT>' . format ( n ) , log_info ) <EOL> self . socket . connect ( ( '<STR_LIT:127.0.0.1>' , self . port ) ) <EOL> self . hsdev_socket = self . socket <EOL> self . hsdev_address = '<STR_LIT:127.0.0.1>' <EOL> self . set_connected ( ) <EOL> self . listener = threading . Thread ( target = self . listen ) <EOL> self . listener . start ( ) <EOL> log ( '<STR_LIT>' , log_info ) <EOL> call_callback ( self . on_connected , name = '<STR_LIT>' ) <EOL> return True <EOL> except Exception as e : <EOL> log ( '<STR_LIT>' . format ( n ) , log_warning ) <EOL> time . sleep ( delay ) <EOL> return False <EOL> @ reconnect_function <EOL> def connect_async ( self , tries = <NUM_LIT:10> , delay = <NUM_LIT:1.0> ) : <EOL> thread = threading . Thread ( <EOL> target = self . connect , <EOL> kwargs = { '<STR_LIT>' : tries , '<STR_LIT>' : delay , '<STR_LIT>' : True } ) <EOL> thread . start ( ) <EOL> def wait ( self , timeout = None ) : <EOL> return self . connected . wait ( timeout ) <EOL> def close ( self ) : <EOL> if self . is_unconnected ( ) : <EOL> return <EOL> self . connected . clear ( ) <EOL> if self . hsdev_socket : <EOL> self . hsdev_socket . close ( ) <EOL> self . hsdev_socket = None <EOL> self . socket . close ( ) <EOL> def is_connecting ( self ) : <EOL> return self . connecting . is_set ( ) <EOL> def is_connected ( self ) : <EOL> return self . connected . is_set ( ) <EOL> def is_unconnected ( self ) : <EOL> return ( not self . is_connecting ( ) ) and ( not self . is_connected ( ) ) <EOL> def set_unconnected ( self ) : <EOL> if self . connecting . is_set ( ) : <EOL> self . connecting . clear ( ) <EOL> if self . connected . is_set ( ) : <EOL> self . connected . clear ( ) <EOL> def set_connecting ( self ) : <EOL> self . set_unconnected ( ) <EOL> self . connecting . set ( ) <EOL> def set_connected ( self ) : <EOL> if self . is_connecting ( ) : <EOL> self . connected . set ( ) <EOL> self . connecting . clear ( ) <EOL> else : <EOL> log ( '<STR_LIT>' , log_debug ) <EOL> def on_receive ( self , id , command , on_response = None , on_notify = None , on_error = None ) : <EOL> with self . map as m : <EOL> m [ id ] = HsDevCallbacks ( id , command , on_response , on_notify , on_error ) <EOL> def verify_connected ( self ) : <EOL> if self . is_connected ( ) : <EOL> return True <EOL> else : <EOL> self . connection_lost ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> return self . is_connected ( ) <EOL> def connection_lost ( self , fn , e ) : <EOL> if self . is_unconnected ( ) : <EOL> return <EOL> self . close ( ) <EOL> log ( '<STR_LIT>' . format ( fn , e ) , log_error ) <EOL> call_callback ( self . on_disconnected , name = '<STR_LIT>' ) <EOL> with self . map as m : <EOL> for on_msg in m . values ( ) : <EOL> on_msg . on_error ( '<STR_LIT>' ) <EOL> m . clear ( ) <EOL> self . id = <NUM_LIT:1> <EOL> self . part = '<STR_LIT>' <EOL> if self . autoconnect : <EOL> self . reconnect ( ) <EOL> def call ( self , command , opts = { } , on_response = None , on_notify = None , on_error = None , wait = False , timeout = None , id = None ) : <EOL> args_cmd = '<STR_LIT>' . format ( command ) <EOL> call_cmd = '<STR_LIT>' . format ( command , opts ) <EOL> if not self . verify_connected ( ) : <EOL> return None if wait else False <EOL> try : <EOL> wait_receive = threading . Event ( ) if wait else None <EOL> x = { } <EOL> def on_response_ ( r ) : <EOL> x [ '<STR_LIT:result>' ] = r <EOL> call_callback ( on_response , r ) <EOL> if wait_receive : <EOL> wait_receive . set ( ) <EOL> def on_error_ ( e , ds ) : <EOL> call_callback ( on_error , e , ds ) <EOL> if wait_receive : <EOL> wait_receive . set ( ) <EOL> if wait or on_response or on_notify or on_error : <EOL> if id is None : <EOL> id = str ( self . id ) <EOL> self . id = self . id + <NUM_LIT:1> <EOL> self . on_receive ( id , args_cmd , on_response_ , on_notify , on_error_ ) <EOL> opts . update ( { '<STR_LIT>' : True } ) <EOL> opts . update ( { '<STR_LIT:id>' : id , '<STR_LIT>' : command } ) <EOL> msg = json . dumps ( opts , separators = ( '<STR_LIT:U+002C>' , '<STR_LIT::>' ) ) <EOL> self . hsdev_socket . sendall ( msg . encode ( '<STR_LIT:utf-8>' ) ) <EOL> self . hsdev_socket . sendall ( '<STR_LIT:\n>' . encode ( '<STR_LIT:utf-8>' ) ) <EOL> log ( call_cmd , log_trace ) <EOL> if wait : <EOL> wait_receive . wait ( timeout ) <EOL> return x . get ( '<STR_LIT:result>' ) <EOL> return True <EOL> except Exception as e : <EOL> log ( '<STR_LIT>' . format ( call_cmd , e ) , log_error ) <EOL> self . connection_lost ( '<STR_LIT>' , e ) <EOL> return False <EOL> def listen ( self ) : <EOL> while self . verify_connected ( ) : <EOL> try : <EOL> resp = json . loads ( self . get_response ( ) ) <EOL> if '<STR_LIT:id>' in resp : <EOL> callbacks = None <EOL> with self . map as m : <EOL> if resp [ '<STR_LIT:id>' ] in m : <EOL> callbacks = m [ resp [ '<STR_LIT:id>' ] ] <EOL> if callbacks : <EOL> if '<STR_LIT>' in resp : <EOL> callbacks . call_notify ( resp [ '<STR_LIT>' ] ) <EOL> if '<STR_LIT:error>' in resp : <EOL> err = resp . pop ( "<STR_LIT:error>" ) <EOL> callbacks . call_error ( err , resp ) <EOL> with self . map as m : <EOL> m . pop ( resp [ '<STR_LIT:id>' ] ) <EOL> if '<STR_LIT:result>' in resp : <EOL> callbacks . call_response ( resp [ '<STR_LIT:result>' ] ) <EOL> with self . map as m : <EOL> m . pop ( resp [ '<STR_LIT:id>' ] ) <EOL> except Exception as e : <EOL> self . connection_lost ( '<STR_LIT>' , e ) <EOL> return <EOL> def get_response ( self ) : <EOL> while not '<STR_LIT:\n>' in self . part : <EOL> self . part = self . part + self . socket . recv ( <NUM_LIT> ) . decode ( '<STR_LIT:utf-8>' ) <EOL> ( r , _ , post ) = self . part . partition ( '<STR_LIT:\n>' ) <EOL> self . part = post <EOL> return r <EOL> @ command <EOL> def link ( self , hold = False , ** kwargs ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : hold } ) <EOL> @ command <EOL> def ping ( self ) : <EOL> return cmd ( '<STR_LIT>' , { } , lambda r : r and ( '<STR_LIT:message>' in r ) and ( r [ '<STR_LIT:message>' ] == '<STR_LIT>' ) ) <EOL> @ async_command <EOL> def scan ( self , cabal = False , sandboxes = [ ] , projects = [ ] , files = [ ] , paths = [ ] , ghc = [ ] , contents = { } , docs = False , infer = False ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : projects , <EOL> '<STR_LIT>' : cabal , <EOL> '<STR_LIT>' : sandboxes , <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : paths , <EOL> '<STR_LIT>' : [ { '<STR_LIT:file>' : f , '<STR_LIT>' : cts } for f , cts in contents . items ( ) ] , <EOL> '<STR_LIT>' : ghc , <EOL> '<STR_LIT>' : docs , <EOL> '<STR_LIT>' : infer } ) <EOL> @ async_command <EOL> def docs ( self , projects = [ ] , files = [ ] , modules = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : projects , <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : modules } ) <EOL> @ async_command <EOL> def infer ( self , projects = [ ] , files = [ ] , modules = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : projects , <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : modules } ) <EOL> @ async_list_command <EOL> def remove ( self , cabal = False , sandboxes = [ ] , projects = [ ] , files = [ ] , packages = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : projects , <EOL> '<STR_LIT>' : cabal , <EOL> '<STR_LIT>' : sandboxes , <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : packages } ) <EOL> @ command <EOL> def remove_all ( self ) : <EOL> return cmd ( '<STR_LIT>' , { } ) <EOL> @ list_command <EOL> def list_modules ( self , project = None , file = None , module = None , deps = None , sandbox = None , cabal = False , db = None , package = None , source = False , standalone = False ) : <EOL> fs = [ ] <EOL> if project : <EOL> fs . append ( { '<STR_LIT>' : project } ) <EOL> if file : <EOL> fs . append ( { '<STR_LIT:file>' : file } ) <EOL> if module : <EOL> fs . append ( { '<STR_LIT>' : module } ) <EOL> if deps : <EOL> fs . append ( { '<STR_LIT>' : deps } ) <EOL> if sandbox : <EOL> fs . append ( { '<STR_LIT>' : { '<STR_LIT>' : sandbox } } ) <EOL> if cabal : <EOL> fs . append ( { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> if db : <EOL> fs . append ( { '<STR_LIT>' : encode_package_db ( db ) } ) <EOL> if package : <EOL> fs . append ( { '<STR_LIT>' : package } ) <EOL> if source : <EOL> fs . append ( '<STR_LIT>' ) <EOL> if standalone : <EOL> fs . append ( '<STR_LIT>' ) <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : fs } , parse_modules_brief ) <EOL> @ list_command <EOL> def list_packages ( self ) : <EOL> return cmd ( '<STR_LIT>' , { } ) <EOL> @ list_command <EOL> def list_projects ( self ) : <EOL> return cmd ( '<STR_LIT>' , { } ) <EOL> @ list_command <EOL> def symbol ( self , input = "<STR_LIT>" , search_type = '<STR_LIT>' , project = None , file = None , module = None , deps = None , sandbox = None , cabal = False , db = None , package = None , source = False , standalone = False , locals = False ) : <EOL> q = { '<STR_LIT:input>' : input , '<STR_LIT:type>' : search_type } <EOL> fs = [ ] <EOL> if project : <EOL> fs . append ( { '<STR_LIT>' : project } ) <EOL> if file : <EOL> fs . append ( { '<STR_LIT:file>' : file } ) <EOL> if module : <EOL> fs . append ( { '<STR_LIT>' : module } ) <EOL> if deps : <EOL> fs . append ( { '<STR_LIT>' : deps } ) <EOL> if sandbox : <EOL> fs . append ( { '<STR_LIT>' : { '<STR_LIT>' : sandbox } } ) <EOL> if cabal : <EOL> fs . append ( { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> if db : <EOL> fs . append ( { '<STR_LIT>' : encode_package_db ( db ) } ) <EOL> if package : <EOL> fs . append ( { '<STR_LIT>' : package } ) <EOL> if source : <EOL> fs . append ( '<STR_LIT>' ) <EOL> if standalone : <EOL> fs . append ( '<STR_LIT>' ) <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : q , '<STR_LIT>' : fs , '<STR_LIT>' : locals } , parse_decls ) <EOL> @ command <EOL> def module ( self , input = "<STR_LIT>" , search_type = '<STR_LIT>' , project = None , file = None , module = None , deps = None , sandbox = None , cabal = False , db = None , package = None , source = False , standalone = False ) : <EOL> q = { '<STR_LIT:input>' : input , '<STR_LIT:type>' : search_type } <EOL> fs = [ ] <EOL> if project : <EOL> fs . append ( { '<STR_LIT>' : project } ) <EOL> if file : <EOL> fs . append ( { '<STR_LIT:file>' : file } ) <EOL> if module : <EOL> fs . append ( { '<STR_LIT>' : module } ) <EOL> if deps : <EOL> fs . append ( { '<STR_LIT>' : deps } ) <EOL> if sandbox : <EOL> fs . append ( { '<STR_LIT>' : { '<STR_LIT>' : sandbox } } ) <EOL> if cabal : <EOL> fs . append ( { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> if db : <EOL> fs . append ( { '<STR_LIT>' : encode_package_db ( db ) } ) <EOL> if package : <EOL> fs . append ( { '<STR_LIT>' : package } ) <EOL> if source : <EOL> fs . append ( '<STR_LIT>' ) <EOL> if standalone : <EOL> fs . append ( '<STR_LIT>' ) <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : q , '<STR_LIT>' : fs } , parse_modules ) <EOL> @ command <EOL> def resolve ( self , file , exports = False ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT:file>' : file , '<STR_LIT>' : exports } , parse_module ) <EOL> @ command <EOL> def project ( self , project = None , path = None ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT:name>' : project } if project else { '<STR_LIT:path>' : path } ) <EOL> @ command <EOL> def sandbox ( self , path ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT:path>' : path } ) <EOL> @ list_command <EOL> def lookup ( self , name , file ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT:name>' : name , '<STR_LIT:file>' : file } , parse_decls ) <EOL> @ list_command <EOL> def whois ( self , name , file ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT:name>' : name , '<STR_LIT:file>' : file } , parse_declarations ) <EOL> @ list_command <EOL> def scope_modules ( self , file , input = '<STR_LIT>' , search_type = '<STR_LIT>' ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : { '<STR_LIT:input>' : input , '<STR_LIT:type>' : search_type } , '<STR_LIT:file>' : file } , parse_modules_brief ) <EOL> @ list_command <EOL> def scope ( self , file , input = '<STR_LIT>' , search_type = '<STR_LIT>' , global_scope = False ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : { '<STR_LIT:input>' : input , '<STR_LIT:type>' : search_type } , '<STR_LIT>' : global_scope , '<STR_LIT:file>' : file } , parse_declarations ) <EOL> @ list_command <EOL> def complete ( self , input , file , wide = False ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : input , '<STR_LIT>' : wide , '<STR_LIT:file>' : file } , parse_declarations ) <EOL> @ list_command <EOL> def hayoo ( self , query , page = None , pages = None ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : query , '<STR_LIT>' : page or <NUM_LIT:0> , '<STR_LIT>' : pages or <NUM_LIT:1> } , parse_decls ) <EOL> @ list_command <EOL> def cabal_list ( self , packages ) : <EOL> cmd ( '<STR_LIT>' , { '<STR_LIT>' : packages } , lambda r : [ parse_cabal_package ( s ) for s in r ] if r else None ) <EOL> @ list_command <EOL> def lint ( self , files = [ ] , contents = { } , hlint = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : [ { '<STR_LIT:file>' : f , '<STR_LIT>' : cts } for f , cts in contents . items ( ) ] , <EOL> '<STR_LIT>' : hlint } ) <EOL> @ list_command <EOL> def check ( self , files = [ ] , contents = { } , ghc = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : [ { '<STR_LIT:file>' : f , '<STR_LIT>' : cts } for f , cts in contents . items ( ) ] , <EOL> '<STR_LIT>' : ghc } ) <EOL> @ list_command <EOL> def check_lint ( self , files = [ ] , contents = { } , ghc = [ ] , hlint = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : [ { '<STR_LIT:file>' : f , '<STR_LIT>' : cts } for f , cts in contents . items ( ) ] , <EOL> '<STR_LIT>' : ghc , <EOL> '<STR_LIT>' : hlint } ) <EOL> @ list_command <EOL> def types ( self , files = [ ] , contents = { } , ghc = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : files , <EOL> '<STR_LIT>' : [ { '<STR_LIT:file>' : f , '<STR_LIT>' : cts } for f , cts in contents . items ( ) ] , <EOL> '<STR_LIT>' : ghc } ) <EOL> @ command <EOL> def ghcmod_lang ( self ) : <EOL> return cmd ( '<STR_LIT>' ) <EOL> @ command <EOL> def ghcmod_flags ( self ) : <EOL> return cmd ( '<STR_LIT>' ) <EOL> @ list_command <EOL> def ghcmod_type ( self , file , line , column = <NUM_LIT:1> , ghc = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { <EOL> '<STR_LIT>' : { '<STR_LIT>' : int ( line ) , '<STR_LIT>' : int ( column ) } , <EOL> '<STR_LIT:file>' : file , <EOL> '<STR_LIT>' : ghc } ) <EOL> @ list_command <EOL> def ghcmod_check ( self , files , ghc = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : files , '<STR_LIT>' : ghc } ) <EOL> @ list_command <EOL> def ghcmod_lint ( self , files , hlint = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : files , '<STR_LIT>' : hlint } ) <EOL> @ list_command <EOL> def ghcmod_check_lint ( self , files , ghc = [ ] , hlint = [ ] ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : files , '<STR_LIT>' : ghc , '<STR_LIT>' : hlint } ) <EOL> @ list_command <EOL> def autofix_show ( self , messages ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : messages } , parse_corrections ) <EOL> @ list_command <EOL> def autofix_fix ( self , messages , rest = [ ] , pure = False ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : messages , '<STR_LIT>' : rest , '<STR_LIT>' : pure } , parse_corrections ) <EOL> @ list_command <EOL> def ghc_eval ( self , exprs ) : <EOL> return cmd ( '<STR_LIT>' , { '<STR_LIT>' : exprs } ) <EOL> @ command <EOL> def exit ( self ) : <EOL> return cmd ( '<STR_LIT>' , { } ) <EOL> def wait_result ( fn , * args , ** kwargs ) : <EOL> wait_receive = threading . Event ( ) <EOL> x = { '<STR_LIT:result>' : None } <EOL> on_resp = kwargs . get ( '<STR_LIT>' ) <EOL> on_err = kwargs . get ( '<STR_LIT>' ) <EOL> def wait_response ( r ) : <EOL> x [ '<STR_LIT:result>' ] = r <EOL> if on_resp : <EOL> on_resp ( r ) <EOL> wait_receive . set ( ) <EOL> def wait_error ( e , ds ) : <EOL> log ( '<STR_LIT>' . format ( e , format_error_details ( ds ) ) ) <EOL> if on_err : <EOL> on_err ( e , ds ) <EOL> wait_receive . set ( ) <EOL> tm = kwargs . pop ( '<STR_LIT>' , <NUM_LIT:0.1> ) <EOL> kwargs [ '<STR_LIT>' ] = wait_response <EOL> kwargs [ '<STR_LIT>' ] = wait_error <EOL> fn ( * args , ** kwargs ) <EOL> wait_receive . wait ( tm ) <EOL> return x [ '<STR_LIT:result>' ] <EOL> class HsDevProcess ( threading . Thread ) : <EOL> def __init__ ( self , port = <NUM_LIT> , cache = None , log_file = None , log_config = None ) : <EOL> super ( HsDevProcess , self ) . __init__ ( ) <EOL> self . process = None <EOL> self . on_start = None <EOL> self . on_exit = None <EOL> self . stop_event = threading . Event ( ) <EOL> self . create_event = threading . Event ( ) <EOL> self . port = port <EOL> self . cache = cache <EOL> self . log_file = log_file <EOL> self . log_config = log_config <EOL> def run ( self ) : <EOL> while True : <EOL> self . create_event . wait ( ) <EOL> self . create_event . clear ( ) <EOL> while not self . stop_event . is_set ( ) : <EOL> self . process = HsDev . run_server ( port = self . port , cache = self . cache , log_file = self . log_file , log_config = self . log_config ) <EOL> if not self . process : <EOL> log ( '<STR_LIT>' , log_error ) <EOL> self . stop_event . set ( ) <EOL> else : <EOL> call_callback ( self . on_start , name = '<STR_LIT>' ) <EOL> self . process . wait ( ) <EOL> call_callback ( self . on_exit , name = '<STR_LIT>' ) <EOL> self . stop_event . clear ( ) <EOL> def active ( self ) : <EOL> return self . process . poll ( ) is None <EOL> def inactive ( self ) : <EOL> return self . process . poll ( ) is not None <EOL> def create ( self ) : <EOL> self . create_event . set ( ) <EOL> def stop ( self ) : <EOL> self . stop_event . set ( ) </s>
