Skip to content

Commit

Permalink
SELECT methods
Browse files Browse the repository at this point in the history
  • Loading branch information
amiraliakbari committed Dec 26, 2013
1 parent fbfa2b8 commit d182493
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
3 changes: 3 additions & 0 deletions inspector/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,9 @@ def __unicode__(self):
return fmt.format(acc=acc_rep, abs=abs_rep, bin=bin_rep, name=self.name, args=args_rep, ret=ret_name,
thr=thr_rep, method_name=method_name)

def __repr__(self):
return 'method:{0}'.format(self.qualified_name)

def set_parent_class(self, parent_class):
"""
:type parent_class: Class
Expand Down
37 changes: 32 additions & 5 deletions inspector/saql/sams.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,32 @@ def verify_query(self, query_def, query_type='SELECT'):
if not query_def[1] in self.QUERY_DEF[query_type][query_def[0]]:
raise ValueError('Query not applicable on these types: {0}'.format(query_def))

def select_candidate_classes(self, query):
""" Give all classes that match queries FROM clause
:param SaqlQuery query: the query
:rtype: list of inspector.models.base.Class
"""
classes = []
for obj in self.parse_identifier(query.select_from):
classes += obj.classes
return classes

def select_candidate_methods(self, query):
""" Give all methods that match queries FROM clause
:param SaqlQuery query: the query
:rtype: list of inspector.models.base.Method
"""
methods = []
if query.select_from_type != 'class':
candidate_classes = self.select_candidate_classes(query)
else:
candidate_classes = self.parse_identifier(query.select_from)
for cc in candidate_classes:
methods += cc.methods
return methods

def run_query(self, query):
if not self.project:
raise ValueError('No project selected!')
Expand All @@ -79,18 +105,19 @@ def run_query(self, query):
sel = ['?', q.select_from_type]
objects = []
if q.is_select_classes():
classes = []
sel[0] = 'class'
self.verify_query(sel)
for obj in self.parse_identifier(q.select_from):
classes += obj.classes
objects = classes
objects = self.select_candidate_classes(q)
elif q.is_select_methods():
sel[0] = 'method'
self.verify_query(sel)
objects = self.select_candidate_methods(q)
elif q.is_select_lines():
sel[0] = 'line'
self.verify_query(sel)
elif q.is_select_instances():
sel[0] = 'instance'
self.verify_query(sel)
else:
raise ValueError('Unsupported query type: {0}'.format(q.select_type))

Expand All @@ -101,7 +128,7 @@ def run_query(self, query):
if not m:
raise ValueError('Invalid WHERE condition: {0}'.format(wcl))
fn_name = m.group(1)
fn_params = [self.parse_token(s) for s in m.group(2).split(',')]
fn_params = [self.parse_token(s) for s in m.group(2).split(',')] if m.group(2) else []
try:
fn_callable = self.QUERY_DEF['FUNCTIONS'][sel[0]][fn_name]
except KeyError:
Expand Down
36 changes: 36 additions & 0 deletions inspector/test/saql_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,39 @@ def test_select_classes(self):
r = self.sams.run_query(q5)
self.assertItemsEqual([c.qualified_name for c in r],
['com.g.issue.IssueFragment'])

def test_select_methods(self):
# TODO: parseError: RefreshIssueTask is an inline class and must be handled correctly
#TODO: parseError: similar for inline class IssuesFragment.IssuePager
q1 = 'SELECT methods FROM class:com.g.issue.IssueFragment'
r = self.sams.run_query(q1)
methods = ['onCreate', 'onActivityCreated', 'onCreateView', 'onViewCreated', 'updateHeader', 'refreshIssue',
'RefreshIssueTask', 'onException', 'onSuccess', 'updateList', 'onDialogResult', 'updateStateItem',
'onPrepareOptionsMenu', 'onCreateOptionsMenu', 'onActivityResult', 'shareIssue',
'openPullRequestCommits', 'onOptionsItemSelected']
self.assertItemsEqual([f.name for f in r], methods)

q2 = "SELECT methods FROM class:com.g.issue.IssueFragment WHERE nameIs('shareIssue')"
r = self.sams.run_query(q2)
self.assertItemsEqual([f.name for f in r], ['shareIssue'])

q3 = "SELECT methods FROM class:com.g.issue.IssueFragment WHERE nameIsLike('^share.*$')"
r = self.sams.run_query(q3)
self.assertItemsEqual([f.name for f in r], ['shareIssue'])

q4 = "SELECT methods FROM project"
r = self.sams.run_query(q4)
self.assertEqual(len(r), 18+16) # should be 17+15 after parse corrections!

q5 = "SELECT methods FROM project WHERE nameIsLike('^.*Issue$')"
r = self.sams.run_query(q5)
self.assertItemsEqual([f.name for f in r], ['refreshIssue', 'shareIssue'])

q6 = "SELECT methods FROM project WHERE nameIs('onCreate')"
r = self.sams.run_query(q6)
self.assertItemsEqual([f.qualified_name for f in r],
['com.g.issue.IssueFragment.onCreate', 'com.g.issue.IssuesFragment.onCreate'])

q7 = "SELECT methods FROM project WHERE isPrivate()"
r = self.sams.run_query(q7)
self.assertEqual(len(r), 6+1)

0 comments on commit d182493

Please sign in to comment.