pycode / sourceindex / parser.py

import sys
import os
import inspect

from rope.base import ast
from rope.refactor import functionutils
from rope.base import pycore, evaluate, pyobjects, project, resources
from rope.base.pyobjectsdef import PyModule, PyPackage, PyClass
		
# TODO: add zipped packages

def stdlib_path():
	path = os.path.dirname(inspect.getsourcefile(inspect))
	if path not in sys.path:
		print >>sys.stderr, "Warning: inspect-module not in sys.path. Could not find determine stdlib path properly"
	return path
	

def tree(top):
	for dirpath, dirnames, filenames in os.walk(top):
		if not os.path.exists(os.path.join(dirpath, "__init__.py")):
			continue
		for name in filenames:
			if name.endswith(".py"):
				yield os.path.join(dirpath, name)


def modules(path):
	if os.path.isdir(path):
		for name in os.listdir(path):
			filename = os.path.join(path, name)
			if os.path.isdir(filename) and "-" not in name:
				if os.path.exists(os.path.join(filename, "__init__.py")):
					# skip check that __init__.py is not a directory
					yield "pkg", filename, name
			elif name.endswith(".py"):
				yield "mod", filename, name[:-3]
	else:
		pass # .endswith("zip") ...


def libraries(path):
	dynload_path = os.path.join(path, "lib-dynload")
	for name in os.listdir(path):
		filename = os.path.join(path, name)
		if not os.path.isdir(filename):
			if name.endswith((".dll", ".so")):
				yield "lib", filename, os.path.splitext(name)[0]
			


def parse(filename):
	prj = project.NoProject()
	pyc = pycore.PyCore(prj)
	#resource = resources.File(prj, filename)
	#if resource.is_folder():
	#	pyobject = PyPackage(pyc, resource, force_errors=False)
	#else:
	#	pyobject = PyModule(pyc, resource=resource, force_errors=False)
	pyobject = pyc.get_string_module(open(filename).read())
	#ast = pyobject.ast_node
	for item in parse_scope(pyobject.get_scope()):
		yield item

	
def find_errors(pymodule):
	from rope.base import ast
	from rope.contrib.finderrors import  _BadAccessFinder
    finder = _BadAccessFinder(pymodule)
    ast.walk(pymodule.get_ast(), finder)
    return finder.errors



def parse_scope(scope):
	kind = scope.get_kind()
	pyobj = scope.pyobject
	if kind == "Function":
		parent = scope.parent
		if parent.get_kind() != "Module":
			parent_scope = parent.pyobject.get_name()
		else:
			parent_scope = ""
		fname = pyobj.get_name()
		line = pyobj.get_ast().lineno
		yield "func", parent_scope, fname, line
		for param in scope.pyobject.get_parameters().keys():
			yield "arg", "", param, line
	elif kind == "Class":
		parent = scope.parent
		if parent.get_kind() != "Module":
			parent_scope = parent.pyobject.get_name()
		else:
			parent_scope = ""
		cname = pyobj.get_name()
		line = pyobj.get_ast().lineno
		yield "class", parent_scope, cname, line
	elif kind == "Module":
		for name, var in scope.get_defined_names().items():
			pyobject = getattr(var, "pyobject", None)
			if pyobject:
				ast = getattr(pyobject, "get_ast", None)
				if ast:
					yield "global", "", name, ast().lineno
	for child in scope.get_scopes():
		for item in parse_scope(child):
			yield item





if __name__ == "__main__":
	std = stdlib_path()
	print std
	mods = list(modules(std))
	print mods
	fn = mods[-1][1]
	print fn
	for item in parse(fn):
		print item
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.