def __init__(self): self.as_super = super(TranslationUnitCache, self) self.as_super.__init__() self.translationUnits = LockedVariable({}) self.parsingList = LockedVariable([]) self.busyList = LockedVariable([]) self.index_parse_options = 13 self.index = None self.debug_options = False
def __init__(self): workerthreadcount = get_setting("worker_threadcount", -1) self.as_super = super(TranslationUnitCache, self) self.as_super.__init__(workerthreadcount) self.translationUnits = LockedVariable({}) self.parsingList = LockedVariable([]) self.busyList = LockedVariable([]) self.index_parse_options = 13 self.index = None self.debug_options = False
def __init__(self, var, fn): LockedVariable.__init__(self, var) self.cache = Cache(var, fn)
class TranslationUnitCache(Worker): STATUS_PARSING = 1 STATUS_REPARSING = 2 STATUS_READY = 3 STATUS_NOT_IN_CACHE = 4 class LockedTranslationUnit(LockedVariable): def __init__(self, var, fn): LockedVariable.__init__(self, var) self.cache = Cache(var, fn) def __init__(self): self.as_super = super(TranslationUnitCache, self) self.as_super.__init__() self.translationUnits = LockedVariable({}) self.parsingList = LockedVariable([]) self.busyList = LockedVariable([]) self.index_parse_options = 13 self.index = None self.debug_options = False def get_status(self, filename): tu = self.translationUnits.lock() pl = self.parsingList.lock() a = filename in tu b = filename in pl self.translationUnits.unlock() self.parsingList.unlock() if a and b: return TranslationUnitCache.STATUS_REPARSING elif a: return TranslationUnitCache.STATUS_READY elif b: return TranslationUnitCache.STATUS_PARSING else: return TranslationUnitCache.STATUS_NOT_IN_CACHE def display_status(self): if get_setting("parse_status_messages", True): self.as_super.display_status() def add_busy(self, filename, task, data): bl = self.busyList.lock() test = filename in bl if test: self.busyList.unlock() # Another thread is already doing something with # this file, so try again later if self.tasks.empty(): try: time.sleep(1) except: pass self.tasks.put((task, data)) return True else: bl.append(filename) self.busyList.unlock() return False def remove_busy(self, filename): bl = self.busyList.lock() try: bl.remove(filename) finally: self.busyList.unlock() def task_parse(self, data): filename, opts, opts_script, on_done = data if self.add_busy(filename, self.task_parse, data): return try: self.set_status("Parsing %s" % filename) self.get_translation_unit(filename, opts, opts_script) self.set_status("Parsing %s done" % filename) finally: l = self.parsingList.lock() try: l.remove(filename) finally: self.parsingList.unlock() self.remove_busy(filename) if not on_done is None: run_in_main_thread(on_done) def task_reparse(self, data): filename, opts, opts_script, unsaved_files, on_done = data if self.add_busy(filename, self.task_reparse, data): return try: self.set_status("Reparsing %s" % filename) tu = self.get_translation_unit(filename, opts, opts_script, unsaved_files) if tu != None: tu.lock() try: tu.var.reparse(unsaved_files) tu.cache = Cache(tu.var, filename) self.set_status("Reparsing %s done" % filename) finally: tu.unlock() finally: l = self.parsingList.lock() try: l.remove(filename) finally: self.parsingList.unlock() self.remove_busy(filename) if not on_done is None: run_in_main_thread(on_done) def task_clear(self, data): tus = self.translationUnits.lock() try: tus.clear() finally: self.translationUnits.unlock() def task_remove(self, data): if self.add_busy(data, self.task_remove, data): return try: tus = self.translationUnits.lock() try: if data in tus: tus.pop(data) finally: self.translationUnits.unlock() finally: self.remove_busy(data) def reparse(self, view, filename, unsaved_files=[], on_done=None): ret = False pl = self.parsingList.lock() if filename not in pl: ret = True pl.append(filename) self.tasks.put(( self.task_reparse, (filename, self.get_opts(view), self.get_opts_script(view), unsaved_files, on_done))) self.parsingList.unlock() return ret def add_ex(self, filename, opts, opts_script, on_done=None): tu = self.translationUnits.lock() pl = self.parsingList.lock() if filename not in tu and filename not in pl: pl.append(filename) self.tasks.put(( self.task_parse, (filename, opts, opts_script, on_done))) self.translationUnits.unlock() self.parsingList.unlock() def add(self, view, filename, on_done=None): ret = False tu = self.translationUnits.lock() pl = self.parsingList.lock() if filename not in tu and filename not in pl: ret = True pl.append(filename) self.tasks.put(( self.task_parse, (filename, self.get_opts(view), self.get_opts_script(view), on_done))) self.translationUnits.unlock() self.parsingList.unlock() return ret def get_opts_script(self, view): return expand_path(get_setting("options_script", None, view), view.window()) def get_opts(self, view): opts = get_path_setting("options", [], view) if not get_setting("dont_prepend_clang_includes", False, view): opts.insert(0, "-I%s/clang/include" % scriptpath) if get_setting("add_language_option", True, view): language = get_language(view) if language == "objc": opts.append("-ObjC") elif language == "objc++": opts.append("-ObjC++") else: opts.append("-x") opts.append(language) additional_language_options = get_setting("additional_language_options", {}, view) if additional_language_options.has_key(language): opts.extend(additional_language_options[language] or []) self.debug_options = get_setting("debug_options", False) self.index_parse_options = get_setting("index_parse_options", 13, view) return opts def get_translation_unit(self, filename, opts=[], opts_script=None, unsaved_files=[]): if self.index == None: self.index = cindex.Index.create() tu = None tus = self.translationUnits.lock() if filename not in tus: self.translationUnits.unlock() pre_script_opts = list(opts) if opts_script: # shlex.split barfs if fed with an unicode strings args = shlex.split(opts_script.encode()) + [filename] process = subprocess.Popen(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) output = process.communicate() if process.returncode: print "The options_script failed with code [%s]" % process.returncode print output[1] else: opts += shlex.split(output[0]) if self.debug_options: print "Will compile file %s with the following options:\n%s" % (filename, opts) opts.append(filename) tu = self.index.parse(None, opts, unsaved_files, self.index_parse_options) if tu != None: tu = TranslationUnitCache.LockedTranslationUnit(tu, filename) tu.opts = pre_script_opts tus = self.translationUnits.lock() tus[filename] = tu self.translationUnits.unlock() else: print "tu is None..." else: tu = tus[filename] recompile = tu.opts != opts if recompile: del tus[filename] self.translationUnits.unlock() if recompile: self.set_status("Options change detected. Will recompile %s" % filename) self.add_ex(filename, opts, opts_script, None) return tu def remove(self, filename): self.tasks.put((self.task_remove, filename)) def clear(self): self.tasks.put((self.task_clear, None))
class TranslationUnitCache(Worker): STATUS_PARSING = 1 STATUS_REPARSING = 2 STATUS_READY = 3 STATUS_NOT_IN_CACHE = 4 class LockedTranslationUnit(LockedVariable): def __init__(self, var, fn): LockedVariable.__init__(self, var) self.cache = Cache(var, fn) def __init__(self): workerthreadcount = get_setting("worker_threadcount", -1) self.as_super = super(TranslationUnitCache, self) self.as_super.__init__(workerthreadcount) self.translationUnits = LockedVariable({}) self.parsingList = LockedVariable([]) self.busyList = LockedVariable([]) self.index_parse_options = 13 self.index = None self.debug_options = False def get_status(self, filename): tu = self.translationUnits.lock() pl = self.parsingList.lock() a = filename in tu b = filename in pl self.translationUnits.unlock() self.parsingList.unlock() if a and b: return TranslationUnitCache.STATUS_REPARSING elif a: return TranslationUnitCache.STATUS_READY elif b: return TranslationUnitCache.STATUS_PARSING else: return TranslationUnitCache.STATUS_NOT_IN_CACHE def display_status(self): if get_setting("parse_status_messages", True): self.as_super.display_status() def add_busy(self, filename, task, data): bl = self.busyList.lock() test = filename in bl if test: self.busyList.unlock() # Another thread is already doing something with # this file, so try again later if self.tasks.empty(): try: time.sleep(1) except: pass self.tasks.put((task, data)) return True else: bl.append(filename) self.busyList.unlock() return False def remove_busy(self, filename): bl = self.busyList.lock() try: bl.remove(filename) finally: self.busyList.unlock() def task_parse(self, data): filename, opts, opts_script, on_done = data if self.add_busy(filename, self.task_parse, data): return try: self.set_status("Parsing %s" % filename) self.get_translation_unit(filename, opts, opts_script) self.set_status("Parsing %s done" % filename) finally: l = self.parsingList.lock() try: l.remove(filename) finally: self.parsingList.unlock() self.remove_busy(filename) if not on_done is None: run_in_main_thread(on_done) def task_reparse(self, data): filename, opts, opts_script, unsaved_files, on_done = data if self.add_busy(filename, self.task_reparse, data): return try: self.set_status("Reparsing %s" % filename) tu = self.get_translation_unit(filename, opts, opts_script, unsaved_files) if tu != None: tu.lock() try: tu.var.reparse(unsaved_files) tu.cache = Cache(tu.var, filename) self.set_status("Reparsing %s done" % filename) finally: tu.unlock() finally: l = self.parsingList.lock() try: l.remove(filename) finally: self.parsingList.unlock() self.remove_busy(filename) if not on_done is None: run_in_main_thread(on_done) def task_clear(self, data): tus = self.translationUnits.lock() try: tus.clear() finally: self.translationUnits.unlock() def task_remove(self, data): if self.add_busy(data, self.task_remove, data): return try: tus = self.translationUnits.lock() try: if data in tus: tus.pop(data) finally: self.translationUnits.unlock() finally: self.remove_busy(data) def reparse(self, view, filename, unsaved_files=[], on_done=None): ret = False pl = self.parsingList.lock() try: if filename not in pl: ret = True pl.append(filename) self.tasks.put( (self.task_reparse, (filename, self.get_opts(view), self.get_opts_script(view), unsaved_files, on_done))) finally: self.parsingList.unlock() return ret def add_ex(self, filename, opts, opts_script, on_done=None): tu = self.translationUnits.lock() pl = self.parsingList.lock() try: if filename not in tu and filename not in pl: pl.append(filename) self.tasks.put( (self.task_parse, (filename, opts, opts_script, on_done))) finally: self.translationUnits.unlock() self.parsingList.unlock() def add(self, view, filename, on_done=None): ret = False tu = self.translationUnits.lock() pl = self.parsingList.lock() try: if filename not in tu and filename not in pl: ret = True opts = self.get_opts(view) opts_script = self.get_opts_script(view) pl.append(filename) self.tasks.put( (self.task_parse, (filename, opts, opts_script, on_done))) finally: self.translationUnits.unlock() self.parsingList.unlock() return ret def get_opts_script(self, view): return expand_path(get_setting("options_script", "", view), view.window()) def get_opts(self, view): opts = get_path_setting("options", [], view) if not get_setting("dont_prepend_clang_includes", False, view): opts.insert(0, "-I%s/clang/include" % scriptpath) if get_setting("add_language_option", True, view): language = get_language(view) if language == "objc": opts.append("-ObjC") elif language == "objc++": opts.append("-ObjC++") else: opts.append("-x") opts.append(language) additional_language_options = get_setting( "additional_language_options", {}, view) if additional_language_options.has_key(language): opts.extend(additional_language_options[language] or []) self.debug_options = get_setting("debug_options", False) self.index_parse_options = get_setting("index_parse_options", 13, view) return opts def get_translation_unit(self, filename, opts=[], opts_script=None, unsaved_files=[]): if self.index == None: self.index = cindex.Index.create() tu = None tus = self.translationUnits.lock() if filename not in tus: self.translationUnits.unlock() pre_script_opts = list(opts) if opts_script: # shlex.split barfs if fed with an unicode strings args = shlex.split(opts_script.encode()) + [filename] process = subprocess.Popen(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) output = process.communicate() if process.returncode: print "The options_script failed with code [%s]" % process.returncode print output[1] else: opts += shlex.split(output[0]) if self.debug_options: print "Will compile file %s with the following options:\n%s" % ( filename, opts) opts.append(filename) tu = self.index.parse(None, opts, unsaved_files, self.index_parse_options) if tu != None: tu = TranslationUnitCache.LockedTranslationUnit(tu, filename) tu.opts = pre_script_opts tus = self.translationUnits.lock() tus[filename] = tu self.translationUnits.unlock() else: print "tu is None..." else: tu = tus[filename] recompile = tu.opts != opts if recompile: del tus[filename] self.translationUnits.unlock() if recompile: self.set_status("Options change detected. Will recompile %s" % filename) self.add_ex(filename, opts, opts_script, None) return tu def remove(self, filename): self.tasks.put((self.task_remove, filename)) def clear(self): self.tasks.put((self.task_clear, None))