Browse Source

Support only searching for symbol decls/uses (fixes #53)

tags/v1.0^2
Ben Kurtovic 10 years ago
parent
commit
36dd97dd1f
5 changed files with 33 additions and 11 deletions
  1. +1
    -1
      bitshift/crawler/crawl.py
  2. +3
    -2
      bitshift/database/__init__.py
  3. +13
    -2
      bitshift/query/__init__.py
  4. +11
    -2
      bitshift/query/nodes.py
  5. +5
    -4
      bitshift/query/tree.py

+ 1
- 1
bitshift/crawler/crawl.py View File

@@ -63,7 +63,7 @@ def crawl():
for thread in threads: for thread in threads:
thread.join() thread.join()
for server in parse_servers: for server in parse_servers:
server.kill()
server.terminate()


def _configure_logging(): def _configure_logging():
# This isn't ideal, since it means the bitshift python package must be kept # This isn't ideal, since it means the bitshift python package must be kept


+ 3
- 2
bitshift/database/__init__.py View File

@@ -153,13 +153,14 @@ class Database(object):
query1 = "INSERT INTO symbols VALUES (DEFAULT, ?, ?, ?)" query1 = "INSERT INTO symbols VALUES (DEFAULT, ?, ?, ?)"
query2 = """INSERT INTO symbol_locations VALUES query2 = """INSERT INTO symbol_locations VALUES
(DEFAULT, ?, ?, ?, ?, ?, ?)""" (DEFAULT, ?, ?, ?, ?, ?, ?)"""
build = lambda id, L, typ: [tuple([id, typ] + list(loc)) for loc in L]


type_id = Symbol.TYPES.index(sym_type) type_id = Symbol.TYPES.index(sym_type)
for (name, assigns, uses) in symbols: for (name, assigns, uses) in symbols:
cursor.execute(query1, (code_id, type_id, name)) cursor.execute(query1, (code_id, type_id, name))
sym_id = cursor.lastrowid sym_id = cursor.lastrowid
params = ([tuple([sym_id, 0] + list(loc)) for loc in assigns] +
[tuple([sym_id, 1] + list(loc)) for loc in uses])
params = [build(sym_id, assigns, Symbol.ASSIGN),
build(sym_id, uses, Symbol.USE)]
cursor.executemany(query2, params) cursor.executemany(query2, params)


def close(self): def close(self):


+ 13
- 2
bitshift/query/__init__.py View File

@@ -170,15 +170,26 @@ class _QueryParser(object):


def _parse_symbol(self, term, stype=Symbol.ALL): def _parse_symbol(self, term, stype=Symbol.ALL):
"""Parse part of a query into a symbol node and return it.""" """Parse part of a query into a symbol node and return it."""
assigns = ("a:", "assign:", "assignment:", "d:", "def:", "definition:",
"decl:", "declare:", "declaration:")
uses = ("u:", "use:", "c:", "call:")
if term.startswith(assigns) or term.startswith(uses):
context = Symbol.ASSIGN if term.startswith(assigns) else Symbol.USE
term_part = term.split(":", 1)[1]
if not term_part:
raise QueryParseException('Incomplete query term: "%s"' % term)
term = term_part
else:
context = Symbol.ALL
literal = self._parse_literal(term) literal = self._parse_literal(term)
if isinstance(literal, String): if isinstance(literal, String):
make_symbol = lambda lit: Symbol(stype, String(lit))
make_symbol = lambda lit: Symbol(context, stype, String(lit))
symbols = self._split_query(literal.string, " \"'") symbols = self._split_query(literal.string, " \"'")
node = make_symbol(symbols.pop()) node = make_symbol(symbols.pop())
while symbols: while symbols:
node = BinaryOp(make_symbol(symbols.pop()), BinaryOp.OR, node) node = BinaryOp(make_symbol(symbols.pop()), BinaryOp.OR, node)
return node return node
return Symbol(stype, literal)
return Symbol(context, stype, literal)


def _parse_function(self, term): def _parse_function(self, term):
"""Parse part of a query into a function node and return it.""" """Parse part of a query into a function node and return it."""


+ 11
- 2
bitshift/query/nodes.py View File

@@ -191,6 +191,9 @@ class Symbol(_Node):
Searches in symbol_type and symbol_name. Searches in symbol_type and symbol_name.
""" """
ALL = -1 ALL = -1
ASSIGN = 0
USE = 1

FUNCTION = 0 FUNCTION = 0
CLASS = 1 CLASS = 1
VARIABLE = 2 VARIABLE = 2
@@ -202,17 +205,20 @@ class Symbol(_Node):
TYPE_REPR = ["FUNCTION", "CLASS", "VARIABLE", "NAMESPACE", "INTERFACE", TYPE_REPR = ["FUNCTION", "CLASS", "VARIABLE", "NAMESPACE", "INTERFACE",
"IMPORT"] "IMPORT"]


def __init__(self, type_, name):
def __init__(self, context, type_, name):
""" """
:type context: int (``ASSIGN`` or ``USE``)
:type type_: int (``ALL``, ``FUNCTION``, ``CLASS``, etc.) :type type_: int (``ALL``, ``FUNCTION``, ``CLASS``, etc.)
:type name: :py:class:`._Literal` :type name: :py:class:`._Literal`
""" """
self.context = context
self.type = type_ self.type = type_
self.name = name self.name = name


def __repr__(self): def __repr__(self):
context = ["ASSIGN", "USE", "ALL"][self.context]
type_ = self.TYPE_REPR[self.type] if self.type >= 0 else "ALL" type_ = self.TYPE_REPR[self.type] if self.type >= 0 else "ALL"
return "Symbol({0}, {1})".format(type_, self.name)
return "Symbol({0}, {1}, {2})".format(context, type_, self.name)


def sortkey(self): def sortkey(self):
return self.name.sortkey() return self.name.sortkey()
@@ -228,6 +234,9 @@ class Symbol(_Node):
cond += " AND symbol_type IN (%s)" % types cond += " AND symbol_type IN (%s)" % types
if self.type != self.ALL: if self.type != self.ALL:
cond += " AND symbol_type = %d" % self.type cond += " AND symbol_type = %d" % self.type
if self.context != self.ALL:
tables |= {"symbol_locations"}
cond += " AND sloc_type = %d" % self.context
return "(" + cond + ")", [name], [], False return "(" + cond + ")", [name], [], False






+ 5
- 4
bitshift/query/tree.py View File

@@ -2,7 +2,7 @@ from . import nodes


__all__ = ["Tree"] __all__ = ["Tree"]


QUERY_TEMPLATE = """SELECT codelet_id, (codelet_rank%s) AS score
QUERY_TEMPLATE = """SELECT codelet_id, MAX(codelet_rank%s) AS score
FROM codelets %s FROM codelets %s
WHERE %s WHERE %s
GROUP BY codelet_id GROUP BY codelet_id
@@ -59,13 +59,14 @@ class Tree(object):
:rtype: 2-tuple of (SQL statement string, query parameter tuple) :rtype: 2-tuple of (SQL statement string, query parameter tuple)
""" """
def get_table_joins(tables): def get_table_joins(tables):
data = [
joins = [
("code", "codelet_code_id", "code_id"), ("code", "codelet_code_id", "code_id"),
("authors", "author_codelet", "codelet_id"), ("authors", "author_codelet", "codelet_id"),
("symbols", "symbol_code", "code_id")
("symbols", "symbol_code", "code_id"),
("symbol_locations", "sloc_symbol", "symbol_id")
] ]
tmpl = "INNER JOIN %s ON %s = %s" tmpl = "INNER JOIN %s ON %s = %s"
for args in data:
for args in joins:
if args[0] in tables: if args[0] in tables:
yield tmpl % args yield tmpl % args




Loading…
Cancel
Save