Example #1
0
    def parse_syminfo(self, syminfo, mod_imported):
        '''Convert a ghc-mod 'browse' result into the expected symbol types
        '''
        name, declinfo = self.get_name_decl(syminfo)

        # The name is an operator name '(++)' -- remove the parens. Does not remove them if name is unit ('()').
        if name[0] == '(' and name[-1] == ')' and len(name) > 2:
            name = name[1:-1]

        decl = None
        if declinfo.startswith('class '):
            ctx, args = self.split_context_args(name, declinfo[len('class '):])
            decl = symbols.Class(name, ctx, args, imported=mod_imported)
        elif declinfo.startswith('data '):
            ctx, args = self.split_context_args(name, declinfo[len('data '):])
            decl = symbols.Data(name, ctx, args, imported=mod_imported)
        elif declinfo.startswith('newtype '):
            ctx, args = self.split_context_args(name,
                                                declinfo[len('newtype '):])
            decl = symbols.Newtype(name, ctx, args, imported=mod_imported)
        elif declinfo.startswith('type '):
            ctx, args = self.split_context_args(name, declinfo[len('type '):])
            decl = symbols.Type(name, ctx, args, imported=mod_imported)
        else:
            # Default to function
            decl = symbols.Function(name, declinfo, imported=mod_imported)

        return decl
Example #2
0
def parse_info(name, contents):
    """
    Parses result of :i <name> command of ghci and returns derived symbols.Declaration
    """
    if name[0].isupper():
        # data, class, type or newtype
        matched = DATA_REGEX.search(contents) or CLASS_REGEX.search(contents)
        if matched:
            what = matched.group('what')
            args = matched.group('args').strip().split(' ') if matched.group('args') else []
            ctx = matched.group('ctx')
            definition = matched.group('def')
            if definition:
                definition.strip()

            if what == 'class':
                return symbols.Class(name, ctx, args)
            elif what == 'data':
                return symbols.Data(name, ctx, args, definition)
            elif what == 'type':
                return symbols.Type(name, ctx, args, definition)
            elif what == 'newtype':
                return symbols.Newtype(name, ctx, args, definition)
            else:
                raise RuntimeError('Unknown type of symbol: {0}'.format(what))

    else:
        # function
        function_regex = r'{0}\s+::\s+(?P<type>.*?)(\s+--(.*))?$'.format(name)
        matched = re.search(function_regex, contents, re.MULTILINE)
        if matched:
            return symbols.Function(name, matched.group('type'))

    return None
Example #3
0
    def module(self,
               project_name,
               lookup='',
               search_type='prefix',
               project=None,
               file=None,
               module=None,
               deps=None,
               sandbox=None,
               cabal=False,
               symdb=None,
               package=None,
               source=False,
               standalone=False,
               **backend_args):
        modsyms = None
        if search_type == 'exact' and re.match(r'\w+(\.\w+)+', lookup):
            backend = self.project_backends.get(project_name)
            modinfo, err = backend.command_backend(
                'browse -d -o ' + lookup) if backend is not None else []
            if Settings.COMPONENT_DEBUG.recv_messages or Settings.COMPONENT_DEBUG.all_messages:
                print('ghc-mod modules: resp =\n{0}'.format(
                    pprint.pformat(modinfo)))

            if not err or 'EXCEPTION' not in ' '.join(err):
                moddecls = {}
                for mdecl in modinfo:
                    decl = None
                    name, declinfo = self.get_name_decl(mdecl)
                    if declinfo.startswith('class '):
                        ctx, args = self.split_context_args(name, declinfo[5:])
                        decl = symbols.Class(name, ctx, args)
                    elif declinfo.startswith('data '):
                        ctx, args = self.split_context_args(name, declinfo[5:])
                        decl = symbols.Data(name, ctx, args)
                    elif declinfo.startswith('newtype '):
                        ctx, args = self.split_context_args(name, declinfo[8:])
                        decl = symbols.Newtype(name, ctx, args)
                    elif declinfo.startswith('type '):
                        ctx, args = self.split_context_args(name, declinfo[5:])
                        decl = symbols.Type(name, ctx, args)
                    else:
                        # Default to function
                        decl = symbols.Function(name, declinfo)

                    if decl is not None:
                        moddecls[name] = decl

                if Settings.COMPONENT_DEBUG.recv_messages or Settings.COMPONENT_DEBUG.all_messages:
                    print('ghc-mod modules: moddecls =\n{0}'.format(
                        pprint.pformat(moddecls)))

                modsyms = symbols.Module(lookup, [], [], moddecls,
                                         symbols.PackageDb(global_db=True))

        return self.dispatch_callbacks([modsyms] if modsyms else [],
                                       **backend_args)
Example #4
0
def parse_declaration(decl):
    what = decl['decl']['what']
    docs = decl.get('docs')
    name = decl['name']
    pos = parse_position(decl.get('pos'))
    imported = []
    if 'imported' in decl and decl['imported']:
        imported = [parse_import(d) for d in decl['imported']]
    defined = None
    if 'defined' in decl and decl['defined']:
        defined = parse_module_id(decl['defined'])

    the_decl = decl['decl']
    decl_info = the_decl.get('info')

    retval = None
    if what == 'function':
        ## Most common path
        retval = symbols.Function(name, the_decl.get('type'), docs, imported,
                                  defined, pos)
    else:
        decl_ctx = decl_info.get('ctx')
        decl_args = decl_info.get('args', [])
        decl_def = decl_info.get('def')

        if what == 'type':
            retval = symbols.Type(name, decl_ctx, decl_args, decl_def, docs,
                                  imported, defined, pos)
        elif what == 'newtype':
            retval = symbols.Newtype(name, decl_ctx, decl_args, decl_def, docs,
                                     imported, defined, pos)
        elif what == 'data':
            retval = symbols.Data(name, decl_ctx, decl_args, decl_def, docs,
                                  imported, defined, pos)
        elif what == 'class':
            retval = symbols.Class(name, decl_ctx, decl_args, decl_def, docs,
                                   imported, defined, pos)

    return retval
Example #5
0
    def to_decl(line):
        matched = re.search(function_regex, line)
        if matched:
            return symbols.Function(matched.group('name'),
                                    matched.group('type'))
        else:
            matched = re.search(type_regex, line)
            if matched:
                decl_type = matched.group('what')
                decl_name = matched.group('name')
                decl_args = matched.group('args')
                decl_args = decl_args.split() if decl_args else []

                if decl_type == 'class':
                    return symbols.Class(decl_name, None, decl_args)
                elif decl_type == 'data':
                    return symbols.Data(decl_name, None, decl_args)
                elif decl_type == 'type':
                    return symbols.Type(decl_name, None, decl_args)
                elif decl_type == 'newtype':
                    return symbols.Newtype(decl_name, None, decl_args)
            else:
                return symbols.Declaration(line)