PyXR

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



0001 # Copyright 2003, Grant T. Olson, see License.txt for details
0002 
0003 from __future__ import generators
0004 from astCrawler import astCrawler
0005 from nsNode import nsNode
0006 import re
0007 import os
0008 import stat
0009 import os.path
0010 import sys
0011 import symbol
0012 from misc import pythonpath, skipInvalidFiles, openPythonFile, InvalidSourceError
0013 import traceback
0014 from parser import ParserError
0015 
0016 class astProcess(astCrawler):
0017     """
0018     Tries to extract classes, functions, and vars from files so we can use the info later
0019     """
0020     def __init__(self, text, nsTree=nsNode(nsNode.ROOT, "XXX"), debugOutput=sys.stdout):
0021         astCrawler.__init__(self, text)
0022         self.nsTree = nsTree
0023         self.currentNode = nsTree
0024         self.debugOutput = debugOutput
0025  
0026     debug = 0
0027     def debugPrint(self, text):
0028         if self.debug:
0029             self.debugOutput.write("%s\n" % text)
0030 
0031     def registerHandlers(self):        
0032         self.handlers[symbol.funcdef] = self.functionHandler
0033         self.handlers[symbol.classdef] = self.classHandler
0034         #self.handlers[symbol.expr_stmt] = self.expressionHandler
0035                                     
0036     def expressionHandler(self, params):
0037         lhs = params[0]
0038         assignType = params[1]
0039         rhs = params [2:]
0040         varName = ""
0041         if lhs[0] == token.NAME:
0042             varName = lhs[1]
0043         else:
0044             varName = str(lhs)
0045         self.debugPrint("NAMESPACE: %s, VARIABLE ASSIGNMENT lsh: %s type: %s rhs: %s" % (self.currentNode, lhs, assignType, rhs))
0046         if not self.currentNode.hasChild(nsNode.VARIABLE, varName):
0047             self.currentNode.addChild(nsNode.VARIABLE, varName)
0048             
0049     def functionHandler(self, params):
0050         defConstant = params[0]
0051         funcName = params[1][1]
0052         parameters = params[2]
0053         colonConst = params[3]
0054         suite = params[4]
0055         
0056         self.debugPrint("NAMESPACE: %s, FUNCTION => %s, PARAMS %s" % (self.currentNode, funcName, parameters))
0057         self.currentNode = self.currentNode.addOrGetChild(nsNode.FUNCTION, funcName)
0058         self.process(suite)
0059         self.currentNode = self.currentNode.parent
0060         
0061     def classHandler(self, params):
0062         classConst = params[0]
0063         className = params[1][1]
0064         rest = params[2:]
0065         y = 2
0066         while params[y][1] != ":":
0067             y += 1
0068         suite = params[y+1]
0069         self.debugPrint("NAMESPACE: %s => CLASS: %s" % (self.currentNode, className))
0070         self.currentNode = self.currentNode.addOrGetChild(nsNode.CLASS, className)
0071         self.debugPrint("CURRENT NODE %s" % self.currentNode)
0072         self.process(suite)
0073         self.currentNode = self.currentNode.parent
0074     
0075 def processFileList(filelist, node=nsNode(nsNode.ROOT, "ROOT")):
0076     for module in filelist:
0077         sys.stdout.write(".");sys.stdout.flush(); #print , adds a space
0078         moduleName = os.path.split(module)[-1] # strip path
0079         moduleName = moduleName[:-3] # strip .py
0080 
0081         f = openPythonFile(module)
0082         txt = f.read()
0083         f.close()
0084         child = node.addChild(nsNode.MODULE,moduleName)
0085         
0086         try:
0087             tmpProcess = astProcess(txt + "\n\n", child)
0088         except KeyboardInterrupt:
0089             raise
0090         except:
0091             if sys.exc_info()[0] not in (ParserError, SyntaxError):
0092                 raise
0093             msg = "\nUnable to process file %s: Doesn't contain vaild python source: " % module
0094             if skipInvalidFiles:
0095                 print >> sys.stderr, msg + "Skipping\n"
0096             else:
0097                 raise InvalidSourceError(msg + "\nSet skipInvalidFiles=1 in settings.cfg to continue on error\n")
0098         else:
0099             tmpProcess.debug = 0
0100             tmpProcess.process()
0101 
0102 def processDir(directoryName, node):
0103     def sourceFiles(currentPath, files):
0104         return [os.path.join(currentPath, x) for x in files if x[-3:] == ".py"]
0105     def packages(currentPath, files):
0106         for aFile in files:
0107             fileName = os.path.join(currentPath, aFile)
0108             mode = os.stat(fileName)[stat.ST_MODE]
0109             if stat.S_ISDIR(mode):
0110                 if os.path.exists( os.path.join(fileName, "__init__.py")):
0111                     yield fileName
0112 
0113     if os.path.exists(directoryName) and os.path.isdir(directoryName):
0114         dirFiles = os.listdir(directoryName)
0115     else:
0116         print >> sys.stderr, "\nDirectory '%s' does not exist, skipping" % directoryName
0117         dirFiles = []
0118     processFileList(sourceFiles(directoryName, dirFiles), node)
0119     for package in packages(directoryName, dirFiles):
0120         processDir(package, node.addChild(nsNode.PACKAGE, package))
0121     
0122 
0123 
0124 def makeTree(paths=pythonpath):
0125     rootNode = nsNode(nsNode.ROOT, "ROOT")
0126     for dir in paths:
0127         processDir(dir, rootNode.addChild(nsNode.DIRECTORY, dir))
0128     print
0129     return rootNode
0130 
0131 if __name__=='__main__':
0132     import sys
0133     if len(sys.argv) != 2:
0134         print "Usage: python astProcess.py cachefile.dat"
0135     else:
0136         x = makeTree()
0137         sys.argv
0138         f = file(sys.argv[1], "w")
0139         x.saveToStream(f.write)
0140         f.close()
0141 
0142 
0143 

Generated by PyXR 0.9.4
SourceForge.net Logo