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
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
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)
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
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)