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
예제 #2
0
 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
예제 #3
0
 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))
예제 #6
0
 def __init__(self, var, fn):
     LockedVariable.__init__(self, var)
     self.cache = Cache(var, fn)
예제 #7
0
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))