PyXR

C:\Python24\Lib\site-packages\pyxr \ nsNode.py



0001 # Copyright 2003, Grant T. Olson, see License.txt for details
0002 
0003 import re, sys, os
0004 
0005 class nsNode:
0006     PACKAGE = 1
0007     MODULE = 2
0008     CLASS = 3
0009     FUNCTION = 4
0010     VARIABLE = 5
0011     GLOBALREF = 6
0012     ROOT = 7
0013     RETURNS = 8
0014     PARAMS = 9
0015     DIRECTORY = 10
0016 
0017     nsStringToType = { "P":PACKAGE, "M":MODULE, "C":CLASS, "F":FUNCTION,"V":VARIABLE, "G":GLOBALREF, "ROOT":ROOT,
0018                        "RET":RETURNS, "PARAM":PARAMS, "DIRECTORY":DIRECTORY}
0019     nsTypeToString = { PACKAGE:"P", MODULE:"M", CLASS:"C", FUNCTION:"F", VARIABLE:"V", GLOBALREF:"G", ROOT:"ROOT",
0020                        RETURNS:"RET", PARAMS:"PARAM", DIRECTORY:"DIRECTORY"}
0021     
0022     splitRE = re.compile(r"\|([^:]+):([^\|\n]+)(.*)").match
0023 
0024     baseHREF = ""
0025     def getPath(self):
0026         import os.path
0027         """ Returns the path in the filesystem """
0028         if self.nsType == nsNode.PACKAGE or self.nsType == nsNode.DIRECTORY:
0029             if self.parent:
0030                 return os.path.join(self.parent.getPath(), self.name)
0031             else:
0032                 return self.name
0033         elif self.nsType == nsNode.MODULE:
0034             if self.parent:
0035                 return os.path.join(self.parent.getPath(), self.name + ".py")
0036             else:
0037                 return self.name + ".py"
0038         else:
0039             return ""
0040         
0041     def splitString(self, string):
0042         """ 3-Tuple: (type, name, rest) """
0043         return nsNode.splitRE(string).groups()
0044 
0045     def getChildType(self, nsType):
0046         return [child for child in self.children if child.nsType == nsType]
0047     def getClasses(self): return self.getChildType(nsNode.CLASS)
0048     def getModules(self): return self.getChildType(nsNode.MODULE)
0049     def getVariables(self): return self.getChildType(nsNode.CLASS)
0050     def getPackages(self): return self.getChildType(nsNode.PACKAGE)
0051     def getFunctions(self): return self.getChildType(nsNode.FUNCTION)
0052     def getDirectories(self): return self.getChildType(nsNode.DIRECTORY)
0053     
0054     def __init__(self, nsType = None, name = "", parentNode = None):
0055         if nsType:
0056             self.nsType = nsType
0057         else:
0058             self.nsType = nsNode.PACKAGE
0059         self.name = name
0060         self.parent = parentNode
0061         if parentNode:
0062             self.root = parentNode.root
0063         else:
0064             self.root = self
0065         self.children = []
0066 
0067     def findNode(self, nodeType, nodeName):
0068         """
0069         Standard depth-first search
0070         Probably best for locating modules and packages
0071         """
0072         if self.nsType == nodeType and self.name == nodeName:
0073             return self
0074         for child in self.children:
0075             tmpMatch = child.findNode(nodeType, nodeName)
0076             if tmpMatch:
0077                 return tmpMatch
0078         return None
0079     
0080     def hasChild(self, childNsType, childName):
0081         for child in self.children:
0082             if child.nsType == childNsType and child.name == childName:
0083                 return 1
0084         return 0
0085 
0086     def getChild(self, childNsType, childName):
0087         for child in self.children:
0088             if child.nsType == childNsType and child.name == childName:
0089                 return child
0090         raise Exception("INVALID CHILD")
0091 
0092     def getAnyChild(self, childName):
0093         for child in self.children:
0094             if child.name == childName:
0095                 return child
0096         return None
0097     
0098     def addChild(self, childNsType, childName):
0099         if self.hasChild(childNsType, childName):
0100             raise Exception("Can't add an existing child(%s %s) to %s" %
0101                             (self.nsTypeToString[childNsType], childName, self))
0102         
0103         tmpChild = nsNode(childNsType, childName, self)
0104         self.children.append(tmpChild)
0105         return tmpChild
0106 
0107     def addOrGetChild(self, childNsType, childName):
0108         """ Just like add, but it will return an existing child instead of throwing an error """
0109         if self.hasChild(childNsType, childName):
0110             return self.getChild(childNsType, childName)
0111         else:
0112             tmpChild = nsNode(childNsType, childName, self)
0113             self.children.append(tmpChild)
0114             return tmpChild
0115         
0116     def saveToStream(self, write=sys.stdout.write):
0117         write(str(self) + "\n")
0118         for child in self.children:
0119             child.saveToStream(write)
0120 
0121     def addFullNode(self, rest):
0122         nsType, name, rest = self.splitString(rest)
0123         nsType = self.nsStringToType[nsType]
0124         tmpNode = self.root
0125 
0126         if tmpNode.nsType != nsType or tmpNode.name != name:
0127             raise Exception ("Invalid Root Node")
0128         while rest:
0129             nsType, name, rest = self.splitString(rest)
0130             nsType = self.nsStringToType[nsType]
0131             if tmpNode.hasChild(nsType, name):
0132                 tmpNode = tmpNode.getChild(nsType, name)
0133             else:
0134                 tmpNode = tmpNode.addChild(nsType, name)
0135 
0136             if not rest:
0137                 break
0138             
0139     def loadFromStream(self, readlines):
0140         for line in readlines():
0141             self.addFullNode(line)
0142             
0143     def __str__(self):
0144         if self.parent:
0145             return str(self.parent) + "|%s:%s" % (self.nsTypeToString[self.nsType], self.name)
0146         else:
0147             return "|%s:%s" % (self.nsTypeToString[self.nsType], self.name)
0148 
0149 
0150 nsNodeTree = None
0151 
0152 
0153 def loadTree():
0154     """ This should be called to load the nodes"""
0155     global nsNodeTree
0156     if not nsNodeTree:
0157         import astProcess
0158         print "Building Index of Source(5-10 minutes)...",
0159         nsNodeTree = astProcess.makeTree()
0160 
0161 def loadTreeFromFile(filename):
0162     """
0163     Load preprocessed node file
0164     this is faster when you're debugging
0165     """
0166     global nsNodeTree
0167     nsNodeTree = nsNode(nsNode.ROOT, "ROOT")
0168     f = file(filename)
0169     nsNodeTree.loadFromStream(f.readlines)
0170     f.close()
0171     
0172 
0173 
0174 def moduleBreadthFirstSearch(nsName, searchList=None):
0175     if searchList == None:
0176         if not nsNodeTree:
0177             loadTree() #hopefully it's already loaded
0178         searchList = [nsNodeTree]
0179     while searchList:
0180         currentNode = searchList[0]
0181         searchList = searchList[1:]
0182         name = currentNode.name.split(os.sep)[-1] #strip path if it's there
0183         if currentNode.nsType in (nsNode.MODULE, nsNode.PACKAGE) and name == nsName:
0184             return currentNode
0185         else:
0186             if currentNode.nsType in (nsNode.ROOT, nsNode.DIRECTORY):
0187                 #only these care about subpackages and directories
0188                 #technically, no other types should have any subpackages or directories)
0189                 searchList.extend(currentNode.getModules())
0190                 searchList.extend(currentNode.getPackages())
0191                 searchList.extend(currentNode.getDirectories())
0192 
0193 def getModuleNode(nsName, searchList = None):
0194     if not nsNodeTree:
0195         loadTree() #this should already be done, but better safe than sorry
0196     return moduleBreadthFirstSearch(nsName, searchList)
0197     #return nsNodeTree.findNode(nsType, nsName)
0198 
0199 
0200 def pathToNode(path):
0201     tmpNode = None
0202     if not nsNodeTree:
0203         loadTree()
0204     #locate starting dir first
0205     directories = nsNodeTree.getDirectories()
0206     dirLen = 0
0207     for directory in directories:
0208         if path.startswith(directory.name) and dirLen < len(directory.name):
0209             tmpNode = directory
0210             dirLen = len(directory.name)
0211 
0212     if not tmpNode: return None
0213 
0214     remainingPath = path[len(tmpNode.name):]
0215     if remainingPath.endswith(".py"):
0216         remainingPath = remainingPath[:-3]
0217     pathItems = [x for x in remainingPath.split(os.sep) if x]
0218 
0219     for item in pathItems:
0220         for currentNode in tmpNode.children:
0221             name = currentNode.name.split(os.sep)[-1] #strip path if it's there
0222             if name == item:
0223                 tmpNode = currentNode
0224                 break
0225             tmpNode = None
0226         if not tmpNode:
0227             return None
0228     return tmpNode

Generated by PyXR 0.9.4
SourceForge.net Logo