def findDefinitionOfName(scope, targetname, pythonpath): while 1: # try scope children childscope = scope.getChild(targetname) if childscope is not None: return convertScopeToMatchObject(childscope,100) # check variables created in this scope for name,line,col, node in scope.getVariablesAssignedInScope(keyword=targetname): return createMatchObject(scope,line,col,name) # try imports match = searchImportedModulesForDefinition(scope,targetname,pythonpath) if match is not None: return match if not isinstance(scope,Module): if scopeIsAMethod(scope): # can't access class scope from a method, scope = scope.getParent().getParent() else: # try parent scope scope = scope.getParent() else: break return None # couldn't find it
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 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 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 generateRefsToName(name,scope,sourcenode,defnmatch,pythonpath): assert scope is not None if isinstance(scope,Function): # can do a local search for linenum,col in scope.getWordCoordsMatchingString(name): potentualMatch = findDefinitionByCoords(sourcenode.filename, linenum, col, pythonpath) if potentualMatch is not None and \ potentualMatch == defnmatch: yield createMatchObject(scope,linenum,col,name,100) else: for match in globalScanForNameReferences(name, sourcenode.filename, defnmatch, pythonpath): yield match
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 searchImportedModulesForDefinition(scope,targetname,pythonpath): for modname, name, alias in scope.getImports(): if name == '*' or targetname in (name,alias): module = resolveImportedModuleOrPackage(scope,modname,pythonpath) if module is None: # couldn't find module continue elif name == '*': # e.g. from foo import * match = findDefinitionOfName(module,targetname,pythonpath) if match is not None: return match elif name == targetname: match = findDefinitionOfName(module,targetname,pythonpath) if match is not None: return match else: if modname == targetname: module = resolveImportedModuleOrPackage(scope,modname, pythonpath) match = createMatchObject(module,0,0,"") return match