def getDefinitionAndScope(sourcenode,lineno,node,pythonpath): scope = getScopeForLine(sourcenode,lineno) if scope.getStartLine() == lineno and \ scope.matchesCompilerNode(node): # scope is the node return scope.getParent(), convertScopeToMatchObject(scope,100) defnmatch = findDefinitionFromASTNode(scope,node,pythonpath) if defnmatch is None: raise CouldntFindDefinitionException("Couldn't find definition") scope = getScopeForLine(sourcenode,defnmatch.lineno) return scope,defnmatch
def moveFunctionToNewModule(origfile, line, newfile): srcnode = getSourceNode(origfile) targetsrcnode = getSourceNode(newfile) scope = getScopeForLine(srcnode, line) linesep = getLineSeperator(srcnode.getLines()[0]) matches = findReferences(origfile, line, scope.getColumnOfName()) origFileImport = [] fromline = 'from %s import %s' % (filenameToModulePath(newfile), scope.name) for match in matches: if match.filename == origfile: origFileImport = fromline + linesep else: s = getSourceNode(match.filename) m = s.fastparseroot if match.lineno in m.getImportLineNumbers(): getUndoStack().addSource(s.filename, s.getSource()) maskedline = m.getLogicalLine(match.lineno) origline = s.getLines()[match.lineno - 1] reMatch = re.match(exactFromRE % (scope.name), maskedline) if reMatch and not (',' in reMatch.group(2) or \ '\\' in reMatch.group(2)): restOfOrigLine = origline[len(reMatch.group(1)):] s.getLines()[match.lineno - 1] = fromline + restOfOrigLine elif re.match(fromRE, maskedline): #remove the element from the import stmt line = re.sub('%s\s*?,' % (scope.name), '', origline) s.getLines()[match.lineno - 1] = line #and add a new line nextline = match.lineno + maskedline.count('\\') + 1 s.getLines()[nextline - 1:nextline - 1] = [fromline + linesep] queueFileToSave(s.filename, s.getSource()) refs = getVariableReferencesInLines(scope.getMaskedLines()) scopeLines = srcnode.getLines()[scope.getStartLine() - 1:scope.getEndLine() - 1] importModules = deduceImportsForNewFile(refs, scope) importlines = composeNewFileImportLines(importModules, linesep) getUndoStack().addSource(srcnode.filename, srcnode.getSource()) getUndoStack().addSource(targetsrcnode.filename, targetsrcnode.getSource()) srcnode.getLines()[scope.getStartLine() - 1:scope.getEndLine() - 1] = origFileImport targetsrcnode.getLines().extend(importlines + scopeLines) queueFileToSave(srcnode.filename, srcnode.getSource()) queueFileToSave(targetsrcnode.filename, targetsrcnode.getSource())
def globalScanForNameReferences(name, filename, defnmatch, pythonpath): for sourcenode, linenum, col in _generateCoordsMatchingString(name,filename,pythonpath): try: potentualMatch = findDefinitionByCoords(sourcenode.filename, linenum, col, pythonpath) if potentualMatch is not None and \ potentualMatch == defnmatch: scope = getScopeForLine(sourcenode,linenum) yield createMatchObject(scope,linenum,col,name,100) except CouldNotLocateNodeException: continue
def _getTypeFromCoordinates(filepath,lineno,col,pythonpath=[]): from bike.query.common import getScopeForLine, translateSourceCoordsIntoASTNode, convertScopeToMatchObject from bike.parsing.load import getSourceNode node = translateSourceCoordsIntoASTNode(filepath,lineno,col) scope = getScopeForLine(getSourceNode(filepath),lineno) scope = getTypeOfExpr(scope,node,pythonpath) if scope is not None: if isinstance(scope,Instance): scope = scope.getType() return convertScopeToMatchObject(scope) else: return None
def _getTypeFromCoordinates(filepath, lineno, col, pythonpath=[]): from bike.query.common import getScopeForLine, translateSourceCoordsIntoASTNode, convertScopeToMatchObject from bike.parsing.load import getSourceNode node = translateSourceCoordsIntoASTNode(filepath, lineno, col) scope = getScopeForLine(getSourceNode(filepath), lineno) scope = getTypeOfExpr(scope, node, pythonpath) if scope is not None: if isinstance(scope, Instance): scope = scope.getType() return convertScopeToMatchObject(scope) else: return None
def moveClassToNewModule(origfile, line, newfile): srcnode = getSourceNode(origfile) targetsrcnode = getSourceNode(newfile) classnode = getScopeForLine(srcnode, line) classlines = srcnode.getLines()[classnode.getStartLine() - 1:classnode.getEndLine() - 1] getUndoStack().addSource(srcnode.filename, srcnode.getSource()) getUndoStack().addSource(targetsrcnode.filename, targetsrcnode.getSource()) srcnode.getLines()[classnode.getStartLine() - 1:classnode.getEndLine() - 1] = [] targetsrcnode.getLines().extend(classlines) queueFileToSave(srcnode.filename, srcnode.getSource()) queueFileToSave(targetsrcnode.filename, targetsrcnode.getSource())
def generateRefsToAttribute(classobj,attrname,pythonpath): rootClasses = getRootClassesOfHierarchy(classobj,pythonpath) for sourcenode, linenum, col in _generateCoordsMatchingString(attrname,classobj.filename,pythonpath): scope = getScopeForLine(sourcenode, linenum) if col != 0 and sourcenode.getLines()[linenum-1][col-1] == '.': # possible attribute expr = translateSourceCoordsIntoASTNode(sourcenode.filename,linenum,col) assert isinstance(expr,Getattr) or isinstance(expr,AssAttr) exprtype = getTypeOfExpr(scope,expr.expr,pythonpath) if isinstance(exprtype,Instance) and \ _isAClassInTheSameHierarchy(exprtype.getType(),rootClasses,pythonpath): yield createMatchObject(scope,linenum,col,attrname,100) elif exprtype is None: # can't deduce type of expression - still could be a match yield createMatchObject(scope,linenum,col,attrname,50) elif scopeIsAMethod(scope) and scope.name == attrname: # possible method if _isAClassInTheSameHierarchy(scope.getParent(),rootClasses,pythonpath): yield convertScopeToMatchObject(scope,100)
def moveClassToNewModule(origfile,line,newfile): srcnode = getSourceNode(origfile) targetsrcnode = getSourceNode(newfile) classnode = getScopeForLine(srcnode,line) classlines = srcnode.getLines()[classnode.getStartLine()-1: classnode.getEndLine()-1] getUndoStack().addSource(srcnode.filename, srcnode.getSource()) getUndoStack().addSource(targetsrcnode.filename, targetsrcnode.getSource()) srcnode.getLines()[classnode.getStartLine()-1: classnode.getEndLine()-1] = [] targetsrcnode.getLines().extend(classlines) queueFileToSave(srcnode.filename,srcnode.getSource()) queueFileToSave(targetsrcnode.filename,targetsrcnode.getSource())
def findDefinitionByCoords(filepath, lineno, col, pythonpath): node = translateSourceCoordsIntoASTNode(filepath,lineno,col) if node is None: raise "selected node type not supported" scope = getScopeForLine(getSourceNode(filepath),lineno) if isinstance(node,compiler.ast.Function) or \ isinstance(node,compiler.ast.Class) or isinstance(node,compiler.ast.Keyword) \ or isinstance(node,FunctionArg): return createMatchObject(scope,lineno,col,node.name,100) if isinstance(node,ModuleName): module = resolveImportedModuleOrPackage(scope,node.modname,pythonpath) return createMatchObject(module,0,0,"") if not isinstance(scope, Module) and lineno == scope.linenum: # looking for defn in fn line scope = scope.getParent() match = findDefinitionFromASTNode(scope,node,pythonpath) return match
def deduceImportsForNewFile(refs, scope): importModules = {} for ref in refs: match = findDefinitionFromASTNode(scope,Name(ref)) if match.filename == scope.module.filename: tgtscope = getScopeForLine(getSourceNode(match.filename), match.lineno) while tgtscope != scope and not isinstance(tgtscope,Module): tgtscope = tgtscope.getParent() if not isinstance(tgtscope,Module): continue # was defined in this function mpath = filenameToModulePath(match.filename) if mpath in importModules: importModules[mpath].append(ref) else: importModules[mpath] = [ref] return importModules
def deduceImportsForNewFile(refs, scope): importModules = {} for ref in refs: match = findDefinitionFromASTNode(scope, Name(ref)) if match.filename == scope.module.filename: tgtscope = getScopeForLine(getSourceNode(match.filename), match.lineno) while tgtscope != scope and not isinstance(tgtscope, Module): tgtscope = tgtscope.getParent() if not isinstance(tgtscope, Module): continue # was defined in this function mpath = filenameToModulePath(match.filename) if mpath in importModules: importModules[mpath].append(ref) else: importModules[mpath] = [ref] return importModules
def findAllPossibleDefinitionsByCoords(filepath,lineno,col): #try: node = translateSourceCoordsIntoASTNode(filepath,lineno,col) #except: # import traceback # traceback.print_exc() if node is None: raise "selected node type not supported" scope = getScopeForLine(getSourceNode(filepath),lineno) match = findDefinitionFromASTNode(scope,node) if match is not None: yield match if isinstance(node,Getattr) and (match is None or match.confidence != 100): root = getRoot() name = node.attrname for match in scanPythonPathForMatchingMethodNames(name,filepath): yield match log.progress.write("done\n")
def findDefinitionOfClassAttributeGivenClass(klass,attrname,pythonpath): assert isinstance(klass,Class) # first scan the method names: for child in klass.getChildNodes(): if child.name == attrname: return convertScopeToMatchObject(child,100) # then scan the method source for attribues for child in klass.getChildNodes(): if isinstance(child,Function): for attr,linenum,col in child.getAssignmentAttributesMatchingKeyword(attrname): exprtype = getTypeOfExpr(child,attr.expr,pythonpath) if isinstance(exprtype,Instance) and exprtype.getType() == klass: return createMatchObject(child,linenum,col,attrname) # try the class scope for name,line,col, node in klass.getVariablesAssignedInScope(keyword=attrname): return createMatchObject(klass,line,col,name) # try base classes for baseclassname in klass.getBaseClassNames(): match = findDefinitionOfName(klass.getParent(),baseclassname,pythonpath) baseclass = getScopeForLine(match.sourcenode,match.lineno) return findDefinitionOfClassAttributeGivenClass(baseclass,attrname,pythonpath)
def moveFunctionToNewModule(origfile,line,newfile): srcnode = getSourceNode(origfile) targetsrcnode = getSourceNode(newfile) scope = getScopeForLine(srcnode,line) linesep = getLineSeperator(srcnode.getLines()[0]) matches =[m for m in findReferences(origfile, line, scope.getColumnOfName())] origFileImport = [] fromline = 'from %s import %s'%(filenameToModulePath(newfile),scope.name) for match in matches: if match.filename == origfile: origFileImport = fromline + linesep else: s = getSourceNode(match.filename) m = s.fastparseroot if match.lineno in m.getImportLineNumbers(): getUndoStack().addSource(s.filename, s.getSource()) maskedline = m.getLogicalLine(match.lineno) origline = s.getLines()[match.lineno-1] reMatch = re.match(exactFromRE%(scope.name),maskedline) if reMatch and not (',' in reMatch.group(2) or \ '\\' in reMatch.group(2)): # i.e. line is 'from module import foo' if match.filename == newfile: #remove the import s.getLines()[match.lineno-1:match.lineno] = [] pass else: restOfOrigLine = origline[len(reMatch.group(1)):] s.getLines()[match.lineno-1] = fromline + restOfOrigLine elif re.match(fromRE,maskedline): # i.e. line is 'from module import foo,bah,baz' #remove the element from the import stmt line = removeNameFromMultipleImportLine(scope.name, origline) s.getLines()[match.lineno-1] = line #and add a new line nextline = match.lineno + maskedline.count('\\') + 1 s.getLines()[nextline-1:nextline-1] = [fromline+linesep] queueFileToSave(s.filename,s.getSource()) refs = getVariableReferencesInLines(scope.getMaskedLines()) scopeLines = srcnode.getLines()[scope.getStartLine()-1: scope.getEndLine()-1] importModules = deduceImportsForNewFile(refs, scope) importlines = composeNewFileImportLines(importModules, linesep) getUndoStack().addSource(srcnode.filename, srcnode.getSource()) getUndoStack().addSource(targetsrcnode.filename, targetsrcnode.getSource()) srcnode.getLines()[scope.getStartLine()-1: scope.getEndLine()-1] = origFileImport targetsrcnode.getLines().extend(importlines+scopeLines) queueFileToSave(srcnode.filename,srcnode.getSource()) queueFileToSave(targetsrcnode.filename,targetsrcnode.getSource())
def getFunctionObject(self): return getScopeForLine(self.sourcenode,self.startline)
def visitFunction(self,node): node = getScopeForLine(self.srcnode, self.lineno) if isinstance(node.getParent(),Class): if node.name == name: self.matches.append(convertNodeToMatchObject(node,50))