This file is indexed.

/usr/share/pyshared/bike/query/common.py is in bicyclerepair 0.9-6.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
from __future__ import generators
from bike.globals import *
from bike.parsing.fastparserast import getRoot, Function, Class, Module, getModule
from bike.parsing.parserutils import generateLogicalLines, makeLineParseable, UnbalancedBracesException, generateLogicalLinesAndLineNumbers
from bike.parsing.newstuff import getSourceNodesContainingRegex
from bike.parsing import visitor
from bike import log
import compiler
from compiler.ast import Getattr, Name
import re

class Match:
    def __repr__(self):
        return ",".join([self.filename, str(self.lineno), str(self.colno),
                         str(self.confidence)])
    def __eq__(self,other):
        if self is None or other is None:
            return False
        return self.filename == other.filename and \
               self.lineno == other.lineno and \
               self.colno == other.colno

def getScopeForLine(sourceNode, lineno):
    scope = None
    childnodes = sourceNode.getFlattenedListOfFastParserASTNodes()
    if childnodes == []:
        return sourceNode.fastparseroot #module node

    scope = sourceNode.fastparseroot

    for node in childnodes:
        if node.linenum > lineno: break
        scope = node

    if scope.getStartLine() != scope.getEndLine(): # is inline
        while scope.getEndLine() <= lineno:
            scope = scope.getParent()
    return scope



# global from the perspective of 'contextFilename'
def globalScanForMatches(contextFilename, matchFinder, targetname):
    for sourcenode in getSourceNodesContainingRegex(targetname, contextFilename):
        print >> log.progress, "Scanning", sourcenode.filename
        searchscope = sourcenode.fastparseroot
        for match in scanScopeForMatches(sourcenode,searchscope,
                                         matchFinder,targetname):
            yield match


def scanScopeForMatches(sourcenode,scope,matchFinder,targetname):
    lineno = scope.getStartLine()
    for line in generateLogicalLines(scope.getMaskedLines()):
        if line.find(targetname) != -1:
            doctoredline = makeLineParseable(line)
            ast = compiler.parse(doctoredline)
            scope = getScopeForLine(sourcenode, lineno)
            matchFinder.reset(line)
            matchFinder.setScope(scope)
            matches = visitor.walk(ast, matchFinder).getMatches()
            for index, confidence in matches:
                match = Match()
                match.filename = sourcenode.filename
                match.sourcenode = sourcenode
                x, y = indexToCoordinates(line, index)
                match.lineno = lineno+y
                match.colno = x
                match.colend = match.colno+len(targetname)
                match.confidence = confidence
                yield match
        lineno+=line.count("\n")
    

def walkLinesContainingStrings(scope,astWalker,targetnames):
    lineno = scope.getStartLine()
    for line in generateLogicalLines(scope.getMaskedLines()):
        if lineContainsOneOf(line,targetnames):
            doctoredline = makeLineParseable(line)
            ast = compiler.parse(doctoredline)
            astWalker.lineno = lineno
            matches = visitor.walk(ast, astWalker)
        lineno+=line.count("\n")


def lineContainsOneOf(line,targetnames):
    for name in targetnames:
        if line.find(name) != -1:
            return True
    return False


# translates an idx in a logical line into physical line coordinates
# returns x and y coords
def indexToCoordinates(src, index):
    y = src[: index].count("\n")
    startOfLineIdx = src.rfind("\n", 0, index)+1
    x = index-startOfLineIdx
    return x, y



# interface for MatchFinder classes
# implement the visit methods
class MatchFinder:
    def setScope(self, scope):
        self.scope = scope

    def reset(self, line):
        self.matches = []
        self.words = re.split("(\w+)", line) # every other one is a non word
        self.positions = []
        i = 0
        for word in self.words:
            self.positions.append(i)
            #if '\n' in word:  # handle newlines
            #    i = len(word[word.index('\n')+1:])
            #else:
            i+=len(word)
        self.index = 0

    def getMatches(self):
        return self.matches

    # need to visit childnodes in same order as they appear
    def visitPrintnl(self,node):
        if node.dest:
            self.visit(node.dest)
        for n in node.nodes:
            self.visit(n)
    
    def visitName(self, node):
        self.popWordsUpTo(node.name)

    def visitClass(self, node):
        self.popWordsUpTo(node.name)
        for base in node.bases:
            self.visit(base)

    def zipArgs(self, argnames, defaults):
        """Takes a list of argument names and (possibly a shorter) list of
        default values and zips them into a list of pairs (argname, default).
        Defaults are aligned so that the last len(defaults) arguments have
        them, and the first len(argnames) - len(defaults) pairs have None as a
        default.
        """
        fixed_args = len(argnames) - len(defaults)
        defaults = [None] * fixed_args + list(defaults)
        return zip(argnames, defaults)

    def visitFunction(self, node):
        self.popWordsUpTo(node.name)
        for arg, default in self.zipArgs(node.argnames, node.defaults):
            self.popWordsUpTo(arg)
            if default is not None:
                self.visit(default)
        self.visit(node.code)

    def visitGetattr(self,node):
        self.visit(node.expr)
        self.popWordsUpTo(node.attrname)

    def visitAssName(self, node):
        self.popWordsUpTo(node.name)

    def visitAssAttr(self, node):
        self.visit(node.expr)
        self.popWordsUpTo(node.attrname)

    def visitImport(self, node):
        for name, alias in node.names:
            for nameelem in name.split("."):
                self.popWordsUpTo(nameelem)
            if alias is not None:
                self.popWordsUpTo(alias)

    def visitFrom(self, node):
        for elem in node.modname.split("."):
            self.popWordsUpTo(elem)
        for name, alias in node.names:
            self.popWordsUpTo(name)
            if alias is not None:
                self.popWordsUpTo(alias)

    def visitLambda(self, node):
        for arg, default in self.zipArgs(node.argnames, node.defaults):
            self.popWordsUpTo(arg)
            if default is not None:
                self.visit(default)
        self.visit(node.code)

    def visitGlobal(self, node):
        for name in node.names:
            self.popWordsUpTo(name)

    def popWordsUpTo(self, word):
        if word == "*":
            return        # won't be able to find this
        posInWords = self.words.index(word)
        idx = self.positions[posInWords]
        self.words = self.words[posInWords+1:]
        self.positions = self.positions[posInWords+1:]

    def appendMatch(self,name,confidence=100):
        idx = self.getNextIndexOfWord(name)
        self.matches.append((idx, confidence))

    def getNextIndexOfWord(self,name):
        return self.positions[self.words.index(name)]

class CouldNotLocateNodeException(Exception): pass

def translateSourceCoordsIntoASTNode(filename,lineno,col):
    module = getModule(filename)
    maskedlines = module.getMaskedModuleLines()
    lline,backtrackchars = getLogicalLine(module, lineno)
    doctoredline = makeLineParseable(lline)
    ast = compiler.parse(doctoredline)
    idx = backtrackchars+col
    nodefinder = ASTNodeFinder(lline,idx)
    node = compiler.walk(ast, nodefinder).node
    if node is None:
        raise CouldNotLocateNodeException("Could not translate editor coordinates into source node")
    return node

def getLogicalLine(module, lineno):
    # we know that the scope is the start of a logical line, so
    # we search from there
    scope = getScopeForLine(module.getSourceNode(), lineno)
    linegenerator = \
            module.generateLinesWithLineNumbers(scope.getStartLine())
    for lline,llinenum in \
            generateLogicalLinesAndLineNumbers(linegenerator):
        if llinenum > lineno:
            break
        prevline = lline
        prevlinenum = llinenum

    backtrackchars = 0
    for i in range(prevlinenum,lineno):
        backtrackchars += len(module.getSourceNode().getLines()[i-1])
    return prevline, backtrackchars



class ASTNodeFinder(MatchFinder):
    # line is a masked line of text
    # lineno and col are coords
    def __init__(self,line,col):
        self.line = line
        self.col = col
        self.reset(line)
        self.node = None

    def visitName(self,node):
        if self.checkIfNameMatchesColumn(node.name):
            self.node = node
        self.popWordsUpTo(node.name)

    def visitGetattr(self,node):
        self.visit(node.expr)
        if self.checkIfNameMatchesColumn(node.attrname):
            self.node = node
        self.popWordsUpTo(node.attrname)

    def visitFunction(self, node):
        if self.checkIfNameMatchesColumn(node.name):
            self.node = node
        self.popWordsUpTo(node.name)

        for arg, default in self.zipArgs(node.argnames, node.defaults):
            if self.checkIfNameMatchesColumn(arg):
                self.node = Name(arg)
            self.popWordsUpTo(arg)
            if default is not None:
                self.visit(default)
        self.visit(node.code)


    visitAssName = visitName
    visitAssAttr = visitGetattr

    def visitClass(self, node):
        if self.checkIfNameMatchesColumn(node.name):
            self.node = node
        self.popWordsUpTo(node.name)
        for base in node.bases:
            self.visit(base)


    def checkIfNameMatchesColumn(self,name):
        idx = self.getNextIndexOfWord(name)
        #print "name",name,"idx",idx,"self.col",self.col
        if idx <= self.col and idx+len(name) > self.col:
            return 1
        return 0

    def visitFrom(self, node):
        for elem in node.modname.split("."):
            self.popWordsUpTo(elem)
        for name, alias in node.names:
            if self.checkIfNameMatchesColumn(name):
                self.node = self._manufactureASTNodeFromFQN(name)
                return
            self.popWordsUpTo(name)
            if alias is not None:
                self.popWordsUpTo(alias)

    # gets round the fact that imports etc dont contain nested getattr
    # nodes for fqns (e.g. import a.b.bah) by converting the fqn
    # string into a getattr instance
    def _manufactureASTNodeFromFQN(self,fqn):
        if "." in fqn:
            assert 0, "getattr not supported yet"
        else:
            return Name(fqn)

def isAMethod(scope,node):
    return isinstance(node,compiler.ast.Function) and \
           isinstance(scope,Class)

def convertNodeToMatchObject(node,confidence=100):
    m = Match()
    m.sourcenode = node.module.getSourceNode()
    m.filename = node.filename
    if isinstance(node,Module):
        m.lineno = 1
        m.colno = 0
    elif isinstance(node,Class) or isinstance(node,Function):
        m.lineno = node.getStartLine()
        m.colno = node.getColumnOfName()
    m.confidence = confidence
    return m