From: <fwi...@us...> - 2008-12-05 01:11:01
|
Revision: 5695 http://jython.svn.sourceforge.net/jython/?rev=5695&view=rev Author: fwierzbicki Date: 2008-12-05 01:10:49 +0000 (Fri, 05 Dec 2008) Log Message: ----------- Merging the astwrite branch into trunk. While I was testing, I noticed some problems stemming from the package names and the "Type" at the end of some of the asdl_antlr.py generated code -- so I fixed that up as well. This checkin changes all of the access on ast nodes to be getters and setters with Lists instead of arrays. The ast nodes also now descend from PyObject instead of Antlr's CommonTree. There are new adapter classes that handle the back and forth of ast nodes from Java to Python. Merged revisions 5586-5592,5594-5595,5597,5612,5628,5633-5634,5636-5637,5641-5643,5660,5672,5677-5679,5683,5685-5686 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/branches/astwrite Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/Lib/ast.py trunk/jython/Lib/inspect.py trunk/jython/Lib/test/test_ast.py trunk/jython/ast/Python.asdl trunk/jython/ast/asdl_antlr.py trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/AST.java trunk/jython/src/org/python/antlr/ErrorHandler.java trunk/jython/src/org/python/antlr/ExpressionParser.java trunk/jython/src/org/python/antlr/FailFastHandler.java trunk/jython/src/org/python/antlr/GrammarActions.java trunk/jython/src/org/python/antlr/InteractiveParser.java trunk/jython/src/org/python/antlr/ListErrorHandler.java trunk/jython/src/org/python/antlr/ModuleParser.java trunk/jython/src/org/python/antlr/PythonTree.java trunk/jython/src/org/python/antlr/ast/Assert.java trunk/jython/src/org/python/antlr/ast/Assign.java trunk/jython/src/org/python/antlr/ast/Attribute.java trunk/jython/src/org/python/antlr/ast/AugAssign.java trunk/jython/src/org/python/antlr/ast/BinOp.java trunk/jython/src/org/python/antlr/ast/BoolOp.java trunk/jython/src/org/python/antlr/ast/Break.java trunk/jython/src/org/python/antlr/ast/Call.java trunk/jython/src/org/python/antlr/ast/ClassDef.java trunk/jython/src/org/python/antlr/ast/Compare.java trunk/jython/src/org/python/antlr/ast/Continue.java trunk/jython/src/org/python/antlr/ast/Delete.java trunk/jython/src/org/python/antlr/ast/Dict.java trunk/jython/src/org/python/antlr/ast/Ellipsis.java trunk/jython/src/org/python/antlr/ast/ErrorExpr.java trunk/jython/src/org/python/antlr/ast/ErrorMod.java trunk/jython/src/org/python/antlr/ast/ErrorSlice.java trunk/jython/src/org/python/antlr/ast/ErrorStmt.java trunk/jython/src/org/python/antlr/ast/Exec.java trunk/jython/src/org/python/antlr/ast/Expr.java trunk/jython/src/org/python/antlr/ast/Expression.java trunk/jython/src/org/python/antlr/ast/ExtSlice.java trunk/jython/src/org/python/antlr/ast/For.java trunk/jython/src/org/python/antlr/ast/FunctionDef.java trunk/jython/src/org/python/antlr/ast/GeneratorExp.java trunk/jython/src/org/python/antlr/ast/Global.java trunk/jython/src/org/python/antlr/ast/If.java trunk/jython/src/org/python/antlr/ast/IfExp.java trunk/jython/src/org/python/antlr/ast/Import.java trunk/jython/src/org/python/antlr/ast/ImportFrom.java trunk/jython/src/org/python/antlr/ast/Index.java trunk/jython/src/org/python/antlr/ast/Interactive.java trunk/jython/src/org/python/antlr/ast/Lambda.java trunk/jython/src/org/python/antlr/ast/List.java trunk/jython/src/org/python/antlr/ast/ListComp.java trunk/jython/src/org/python/antlr/ast/Module.java trunk/jython/src/org/python/antlr/ast/Name.java trunk/jython/src/org/python/antlr/ast/Num.java trunk/jython/src/org/python/antlr/ast/Pass.java trunk/jython/src/org/python/antlr/ast/Print.java trunk/jython/src/org/python/antlr/ast/Raise.java trunk/jython/src/org/python/antlr/ast/Repr.java trunk/jython/src/org/python/antlr/ast/Return.java trunk/jython/src/org/python/antlr/ast/Slice.java trunk/jython/src/org/python/antlr/ast/Str.java trunk/jython/src/org/python/antlr/ast/Subscript.java trunk/jython/src/org/python/antlr/ast/Suite.java trunk/jython/src/org/python/antlr/ast/TryExcept.java trunk/jython/src/org/python/antlr/ast/TryFinally.java trunk/jython/src/org/python/antlr/ast/Tuple.java trunk/jython/src/org/python/antlr/ast/UnaryOp.java trunk/jython/src/org/python/antlr/ast/VisitorBase.java trunk/jython/src/org/python/antlr/ast/VisitorIF.java trunk/jython/src/org/python/antlr/ast/While.java trunk/jython/src/org/python/antlr/ast/With.java trunk/jython/src/org/python/antlr/ast/Yield.java trunk/jython/src/org/python/antlr/ast/boolopType.java trunk/jython/src/org/python/antlr/ast/cmpopType.java trunk/jython/src/org/python/antlr/ast/expr_contextType.java trunk/jython/src/org/python/antlr/ast/operatorType.java trunk/jython/src/org/python/antlr/ast/unaryopType.java trunk/jython/src/org/python/compiler/ArgListCompiler.java trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/compiler/Future.java trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/compiler/ProxyMaker.java trunk/jython/src/org/python/compiler/ScopeInfo.java trunk/jython/src/org/python/compiler/ScopesCompiler.java trunk/jython/src/org/python/core/AbstractArray.java trunk/jython/src/org/python/core/CollectionProxy.java trunk/jython/src/org/python/core/ParserFacade.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyInstance.java trunk/jython/src/org/python/core/PyList.java trunk/jython/src/org/python/core/__builtin__.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/modules/Setup.java Added Paths: ----------- trunk/jython/src/org/python/antlr/adapter/ trunk/jython/src/org/python/antlr/adapter/AliasAdapter.java trunk/jython/src/org/python/antlr/adapter/AstAdapter.java trunk/jython/src/org/python/antlr/adapter/AstAdapters.java trunk/jython/src/org/python/antlr/adapter/CmpopAdapter.java trunk/jython/src/org/python/antlr/adapter/ComprehensionAdapter.java trunk/jython/src/org/python/antlr/adapter/ExcepthandlerAdapter.java trunk/jython/src/org/python/antlr/adapter/ExprAdapter.java trunk/jython/src/org/python/antlr/adapter/IdentifierAdapter.java trunk/jython/src/org/python/antlr/adapter/KeywordAdapter.java trunk/jython/src/org/python/antlr/adapter/SliceAdapter.java trunk/jython/src/org/python/antlr/adapter/StmtAdapter.java trunk/jython/src/org/python/antlr/ast/AstModule.java trunk/jython/src/org/python/antlr/ast/ExceptHandler.java trunk/jython/src/org/python/antlr/base/ trunk/jython/src/org/python/antlr/base/excepthandler.java trunk/jython/src/org/python/antlr/base/expr.java trunk/jython/src/org/python/antlr/base/mod.java trunk/jython/src/org/python/antlr/base/slice.java trunk/jython/src/org/python/antlr/base/stmt.java trunk/jython/src/org/python/antlr/op/ trunk/jython/src/org/python/antlr/op/Add.java trunk/jython/src/org/python/antlr/op/And.java trunk/jython/src/org/python/antlr/op/AugLoad.java trunk/jython/src/org/python/antlr/op/AugStore.java trunk/jython/src/org/python/antlr/op/BitAnd.java trunk/jython/src/org/python/antlr/op/BitOr.java trunk/jython/src/org/python/antlr/op/BitXor.java trunk/jython/src/org/python/antlr/op/Del.java trunk/jython/src/org/python/antlr/op/Div.java trunk/jython/src/org/python/antlr/op/Eq.java trunk/jython/src/org/python/antlr/op/FloorDiv.java trunk/jython/src/org/python/antlr/op/Gt.java trunk/jython/src/org/python/antlr/op/GtE.java trunk/jython/src/org/python/antlr/op/In.java trunk/jython/src/org/python/antlr/op/Invert.java trunk/jython/src/org/python/antlr/op/Is.java trunk/jython/src/org/python/antlr/op/IsNot.java trunk/jython/src/org/python/antlr/op/LShift.java trunk/jython/src/org/python/antlr/op/Load.java trunk/jython/src/org/python/antlr/op/Lt.java trunk/jython/src/org/python/antlr/op/LtE.java trunk/jython/src/org/python/antlr/op/Mod.java trunk/jython/src/org/python/antlr/op/Mult.java trunk/jython/src/org/python/antlr/op/Not.java trunk/jython/src/org/python/antlr/op/NotEq.java trunk/jython/src/org/python/antlr/op/NotIn.java trunk/jython/src/org/python/antlr/op/Or.java trunk/jython/src/org/python/antlr/op/Param.java trunk/jython/src/org/python/antlr/op/Pow.java trunk/jython/src/org/python/antlr/op/RShift.java trunk/jython/src/org/python/antlr/op/Store.java trunk/jython/src/org/python/antlr/op/Sub.java trunk/jython/src/org/python/antlr/op/UAdd.java trunk/jython/src/org/python/antlr/op/USub.java trunk/jython/src/org/python/core/AstList.java Removed Paths: ------------- trunk/jython/Lib/_ast.py trunk/jython/src/org/python/antlr/adapter/AliasAdapter.java trunk/jython/src/org/python/antlr/adapter/AstAdapter.java trunk/jython/src/org/python/antlr/adapter/AstAdapters.java trunk/jython/src/org/python/antlr/adapter/CmpopAdapter.java trunk/jython/src/org/python/antlr/adapter/ComprehensionAdapter.java trunk/jython/src/org/python/antlr/adapter/ExcepthandlerAdapter.java trunk/jython/src/org/python/antlr/adapter/ExprAdapter.java trunk/jython/src/org/python/antlr/adapter/IdentifierAdapter.java trunk/jython/src/org/python/antlr/adapter/KeywordAdapter.java trunk/jython/src/org/python/antlr/adapter/SliceAdapter.java trunk/jython/src/org/python/antlr/adapter/StmtAdapter.java trunk/jython/src/org/python/antlr/ast/aliasType.java trunk/jython/src/org/python/antlr/ast/argumentsType.java trunk/jython/src/org/python/antlr/ast/comprehensionType.java trunk/jython/src/org/python/antlr/ast/excepthandlerType.java trunk/jython/src/org/python/antlr/ast/exprType.java trunk/jython/src/org/python/antlr/ast/keywordType.java trunk/jython/src/org/python/antlr/ast/modType.java trunk/jython/src/org/python/antlr/ast/sliceType.java trunk/jython/src/org/python/antlr/ast/stmtType.java Property Changed: ---------------- trunk/jython/ trunk/jython/ast/ trunk/jython/src/org/python/antlr/ trunk/jython/src/org/python/antlr/ast/ trunk/jython/src/org/python/compiler/ Property changes on: trunk/jython ___________________________________________________________________ Modified: svnmerge-integrated - /branches/astwrite:1-5585 + /branches/astwrite:1-5692 Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/CoreExposed.includes 2008-12-05 01:10:49 UTC (rev 5695) @@ -55,3 +55,64 @@ org/python/modules/zipimport/zipimporter.class org/python/modules/PyStruct.class org/python/modules/PyTeeIterator.class +org/python/antlr/AST.class +org/python/antlr/ast/AsmModule.class +org/python/antlr/ast/And.class +org/python/antlr/ast/BitXor.class +org/python/antlr/ast/Gt.class +org/python/antlr/ast/AugLoad.class +org/python/antlr/ast/Mult.class +org/python/antlr/ast/NotEq.class +org/python/antlr/ast/LShift.class +org/python/antlr/ast/IsNot.class +org/python/antlr/ast/RShift.class +org/python/antlr/ast/Eq.class +org/python/antlr/ast/BitOr.class +org/python/antlr/ast/Div.class +org/python/antlr/ast/LtE.class +org/python/antlr/ast/Store.class +org/python/antlr/ast/Not.class +org/python/antlr/ast/BitAnd.class +org/python/antlr/ast/In.class +org/python/antlr/ast/UAdd.class +org/python/antlr/ast/GtE.class +org/python/antlr/ast/Lt.class +org/python/antlr/ast/Mod.class +org/python/antlr/ast/Sub.class +org/python/antlr/ast/Del.class +org/python/antlr/ast/Pow.class +org/python/antlr/ast/Invert.class +org/python/antlr/ast/Is.class +org/python/antlr/ast/Load.class +org/python/antlr/ast/Add.class +org/python/antlr/ast/AugStore.class +org/python/antlr/ast/Delete.class +org/python/antlr/ast/GeneratorExp.class +org/python/antlr/ast/Import.class +org/python/antlr/ast/comprehensionType.class +org/python/antlr/ast/With.class +org/python/antlr/ast/Module.class +org/python/antlr/ast/Global.class +org/python/antlr/ast/Dict.class +org/python/antlr/ast/ClassDef.class +org/python/antlr/ast/ExceptHandler.class +org/python/antlr/ast/TryExcept.class +org/python/antlr/ast/Tuple.class +org/python/antlr/ast/ListComp.class +org/python/antlr/ast/TryFinally.class +org/python/antlr/ast/If.class +org/python/antlr/ast/ImportFrom.class +org/python/antlr/ast/FunctionDef.class +org/python/antlr/ast/argumentsType.class +org/python/antlr/ast/List.class +org/python/antlr/ast/Interactive.class +org/python/antlr/ast/ExtSlice.class +org/python/antlr/ast/Compare.class +org/python/antlr/ast/While.class +org/python/antlr/ast/Call.class +org/python/antlr/ast/Assign.class +org/python/antlr/ast/For.class +org/python/antlr/ast/Suite.class +org/python/antlr/ast/BoolOp.class +org/python/antlr/ast/Print.class + Deleted: trunk/jython/Lib/_ast.py =================================================================== --- trunk/jython/Lib/_ast.py 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/Lib/_ast.py 2008-12-05 01:10:49 UTC (rev 5695) @@ -1,79 +0,0 @@ -from org.python.antlr.ast.boolopType import And,Or -from org.python.antlr.ast.operatorType import Add,Sub,Mult,Div,FloorDiv,Mod,LShift,RShift,BitOr,BitAnd,BitXor,Pow -from org.python.antlr.ast.cmpopType import Eq,Gt,GtE,In,Is,IsNot,Lt,LtE,NotEq,NotIn -from org.python.antlr.ast.unaryopType import Invert,Not,UAdd,USub -from org.python.core.PyTableCode import PyCF_ONLY_AST -from org.python.antlr.ast.expr_contextType import Load, Store, Del, AugLoad, AugStore, Param - -from org.python.antlr import AST - -from org.python.antlr.ast import Assert -from org.python.antlr.ast import Assign -from org.python.antlr.ast import Attribute -from org.python.antlr.ast import AugAssign -from org.python.antlr.ast import BinOp -from org.python.antlr.ast import BoolOp -from org.python.antlr.ast import Break -from org.python.antlr.ast import Call -from org.python.antlr.ast import ClassDef -from org.python.antlr.ast import Compare -from org.python.antlr.ast import Continue -from org.python.antlr.ast import Delete -from org.python.antlr.ast import Dict -from org.python.antlr.ast import Ellipsis -from org.python.antlr.ast import Exec -from org.python.antlr.ast import Expr -from org.python.antlr.ast import Expression -from org.python.antlr.ast import ExtSlice -from org.python.antlr.ast import For -from org.python.antlr.ast import FunctionDef -from org.python.antlr.ast import GeneratorExp -from org.python.antlr.ast import Global -from org.python.antlr.ast import If -from org.python.antlr.ast import IfExp -from org.python.antlr.ast import Import -from org.python.antlr.ast import ImportFrom -from org.python.antlr.ast import Index -from org.python.antlr.ast import Interactive -from org.python.antlr.ast import Lambda -from org.python.antlr.ast import List -from org.python.antlr.ast import ListComp -from org.python.antlr.ast import Module -from org.python.antlr.ast import Name -from org.python.antlr.ast import Num -from org.python.antlr.ast import Pass -from org.python.antlr.ast import Print -from org.python.antlr.ast import Raise -from org.python.antlr.ast import Repr -from org.python.antlr.ast import Return -from org.python.antlr.ast import Slice -from org.python.antlr.ast import Str -from org.python.antlr.ast import Subscript -from org.python.antlr.ast import Suite -from org.python.antlr.ast import TryExcept -from org.python.antlr.ast import TryFinally -from org.python.antlr.ast import Tuple -from org.python.antlr.ast import UnaryOp -#from org.python.antlr.ast import Unicode -from org.python.antlr.ast import While -from org.python.antlr.ast import With -from org.python.antlr.ast import Yield - -import org.python.antlr.ast.aliasType as alias -import org.python.antlr.ast.argumentsType as arguments -import org.python.antlr.ast.boolopType as boolop -import org.python.antlr.ast.cmpopType as cmpop -import org.python.antlr.ast.comprehensionType as comprehension -import org.python.antlr.ast.excepthandlerType as excepthandler -import org.python.antlr.ast.exprType as expr -import org.python.antlr.ast.expr_contextType as expr_context -import org.python.antlr.ast.keywordType as keyword -import org.python.antlr.ast.modType as mod -import org.python.antlr.ast.operatorType as operator -import org.python.antlr.ast.sliceType as slice -import org.python.antlr.ast.stmtType as stmt -import org.python.antlr.ast.unaryopType as unaryop - -#Set to the same value as the CPython version we are targetting. -#note that this number comes from the revision number in CPython's repository. -__version__ = 43614 Modified: trunk/jython/Lib/ast.py =================================================================== --- trunk/jython/Lib/ast.py 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/Lib/ast.py 2008-12-05 01:10:49 UTC (rev 5695) @@ -29,31 +29,6 @@ from _ast import * from _ast import __version__ -if sys.platform.startswith('java'): - import array - - ast_list = array.ArrayType - - def get_class_name(t): - result = t.__class__.__name__ - if result in ("expr_contextType", - "boolopType", - "unaryopType", - "cmpopType", - "operatorType"): - result = str(t) - if result == "AugLoad": - result = "Load" - elif result == "AugStore": - result = "Store" - elif result.endswith("Type"): - result = result[:-4] - return result -else: - ast_list = list - get_class_name = lambda node: node.__class__.__name__ - - def parse(expr, filename='<unknown>', mode='exec'): """ Parse an expression into an AST node. @@ -105,7 +80,7 @@ def _format(node): if isinstance(node, AST): fields = [(a, _format(b)) for a, b in iter_fields(node)] - rv = '%s(%s' % (get_class_name(node), ', '.join( + rv = '%s(%s' % (node.__class__.__name__, ', '.join( ('%s=%s' % field for field in fields) if annotate_fields else (b for a, b in fields) @@ -115,11 +90,11 @@ rv += ', '.join('%s=%s' % (a, _format(getattr(node, a))) for a in node._attributes) return rv + ')' - elif isinstance(node, ast_list): + elif hasattr(node, "__iter__"): return '[%s]' % ', '.join(_format(x) for x in node) return repr(node) if not isinstance(node, AST): - raise TypeError('expected AST, got %r' % get_class_name(node)) + raise TypeError('expected AST, got %r' % node.__class__.__name__) return _format(node) @@ -193,7 +168,7 @@ for name, field in iter_fields(node): if isinstance(field, AST): yield field - elif isinstance(field, ast_list): + elif hasattr(field, "__iter__"): for item in field: if isinstance(item, AST): yield item @@ -206,7 +181,7 @@ will be raised. """ if not isinstance(node, (FunctionDef, ClassDef, Module)): - raise TypeError("%r can't have docstrings" % get_class_name(node)) + raise TypeError("%r can't have docstrings" % node.__class__.__name__) if node.body and isinstance(node.body[0], Expr) and \ isinstance(node.body[0].value, Str): if clean: @@ -251,14 +226,14 @@ def visit(self, node): """Visit a node.""" - method = 'visit_' + get_class_name(node) + method = 'visit_' + node.__class__.__name__ visitor = getattr(self, method, self.generic_visit) return visitor(node) def generic_visit(self, node): """Called if no explicit visitor function exists for a node.""" for field, value in iter_fields(node): - if isinstance(value, ast_list): + if hasattr(value, "__iter__"): for item in value: if isinstance(item, AST): self.visit(item) @@ -305,7 +280,7 @@ def generic_visit(self, node): for field, old_value in iter_fields(node): old_value = getattr(node, field, None) - if isinstance(old_value, ast_list): + if hasattr(old_value, "__iter__"): new_values = [] for value in old_value: if isinstance(value, AST): Modified: trunk/jython/Lib/inspect.py =================================================================== --- trunk/jython/Lib/inspect.py 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/Lib/inspect.py 2008-12-05 01:10:49 UTC (rev 5695) @@ -315,6 +315,13 @@ return None if not isinstance(doc, types.StringTypes): return None + return cleandoc(doc) + +def cleandoc(doc): + """Clean up indentation from docstrings. + + Any whitespace that can be uniformly removed from the second line + onwards is removed.""" try: lines = string.split(string.expandtabs(doc), '\n') except UnicodeError: Modified: trunk/jython/Lib/test/test_ast.py =================================================================== --- trunk/jython/Lib/test/test_ast.py 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/Lib/test/test_ast.py 2008-12-05 01:10:49 UTC (rev 5695) @@ -1,36 +1,22 @@ -#Taken and modified from CPython's release25-maint branch, revision 62446. -import sys,os, itertools +import sys, itertools, unittest +from test import test_support import ast -def get_class_name(t): - result = t.__class__.__name__ - if os.name.startswith('java'): - if result in ("expr_contextType", - "boolopType", - "unaryopType", - "cmpopType", - "operatorType"): - result = t.name() - else: - result = result.split(".")[-1] - if result.endswith("Type"): - result = result[:-4] - return result - def to_tuple(t): if t is None or isinstance(t, (basestring, int, long, complex)): return t - elif hasattr(t, '__iter__'): + elif hasattr(t, "__iter__"): return [to_tuple(e) for e in t] - result = [get_class_name(t)] + result = [t.__class__.__name__] if hasattr(t, 'lineno') and hasattr(t, 'col_offset'): result.append((t.lineno, t.col_offset)) - if not hasattr(t, '_fields') or t._fields is None: + if t._fields is None: return tuple(result) for f in t._fields: result.append(to_tuple(getattr(t, f))) return tuple(result) + # These tests are compiled through "exec" # There should be atleast one test per statement exec_tests = [ @@ -134,49 +120,192 @@ # TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension # excepthandler, arguments, keywords, alias -if __name__=='__main__' and sys.argv[1:] == ['-g']: - for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), - (eval_tests, "eval")): - print kind+"_results = [" - for s in statements: - print repr(to_tuple(compile(s, "?", kind, 0x400)))+"," - print "]" - print "run_tests()" - raise SystemExit +class AST_Tests(unittest.TestCase): -def test_order(ast_node, parent_pos): - - if (not isinstance(ast_node, ast.AST) - or not hasattr(ast_node, '_fields') - or ast_node._fields == None): + def _assert_order(self, ast_node, parent_pos): + if not isinstance(ast_node, ast.AST) or ast_node._fields is None: return - if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)): - node_pos = (ast_node.lineno, ast_node.col_offset) - assert node_pos >= parent_pos, (node_pos, parent_pos) - parent_pos = (ast_node.lineno, ast_node.col_offset) - for name in ast_node._fields: - value = getattr(ast_node, name) - if hasattr(value, '__iter__'): - for child in value: - test_order(child, parent_pos) - elif value != None: - test_order(value, parent_pos) + if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)): + node_pos = (ast_node.lineno, ast_node.col_offset) + self.assert_(node_pos >= parent_pos) + parent_pos = (ast_node.lineno, ast_node.col_offset) + for name in ast_node._fields: + value = getattr(ast_node, name) + if hasattr(value, "__iter__"): + for child in value: + self._assert_order(child, parent_pos) + elif value is not None: + self._assert_order(value, parent_pos) -def run_tests(): - for input, output, kind in ((exec_tests, exec_results, "exec"), - (single_tests, single_results, "single"), - (eval_tests, eval_results, "eval")): - for i, o in itertools.izip(input, output): - ast_tree = compile(i, "?", kind, 0x400) - assert to_tuple(ast_tree) == o, "expected %s, got %s" % ( - o, to_tuple(ast_tree)) - test_order(ast_tree, (0, 0)) + def test_snippets(self): + for input, output, kind in ((exec_tests, exec_results, "exec"), + (single_tests, single_results, "single"), + (eval_tests, eval_results, "eval")): + for i, o in itertools.izip(input, output): + ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST) + self.assertEquals(to_tuple(ast_tree), o) + self._assert_order(ast_tree, (0, 0)) -# XXX: AugStore added for Jython. Short term it is too hard to emit just "Store" as CPython does. + def test_nodeclasses(self): + x = ast.BinOp(1, 2, 3, lineno=0) + self.assertEquals(x.left.n, 1) + self.assertEquals(int(x.op), 2) + self.assertEquals(x.right.n, 3) + self.assertEquals(x.lineno, 0) + + # node raises exception when not given enough arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2) + + # can set attributes through kwargs too + x = ast.BinOp(left=1, op=2, right=3, lineno=0) + self.assertEquals(x.left.n, 1) + self.assertEquals(int(x.op), 2) + self.assertEquals(x.right.n, 3) + self.assertEquals(x.lineno, 0) + + # this used to fail because Sub._fields was None + x = ast.Sub() + + def test_pickling(self): + import pickle + mods = [pickle] + try: + import cPickle + mods.append(cPickle) + except ImportError: + pass + protocols = [0, 1, 2] + for mod in mods: + for protocol in protocols: + for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests): + ast2 = mod.loads(mod.dumps(ast, protocol)) + self.assertEquals(to_tuple(ast2), to_tuple(ast)) + + +class ASTHelpers_Test(unittest.TestCase): + + def test_parse(self): + a = ast.parse('foo(1 + 1)') + b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST) + self.assertEqual(ast.dump(a), ast.dump(b)) + + def test_dump(self): + node = ast.parse('spam(eggs, "and cheese")') + self.assertEqual(ast.dump(node), + "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), " + "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], " + "keywords=[], starargs=None, kwargs=None))])" + ) + self.assertEqual(ast.dump(node, annotate_fields=False), + "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), " + "Str('and cheese')], [], None, None))])" + ) + self.assertEqual(ast.dump(node, include_attributes=True), + "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), " + "lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), " + "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, " + "col_offset=11)], keywords=[], starargs=None, kwargs=None, " + "lineno=1, col_offset=0), lineno=1, col_offset=0)])" + ) + + def test_copy_location(self): + src = ast.parse('1 + 1', mode='eval') + src.body.right = ast.copy_location(ast.Num(2), src.body.right) + self.assertEqual(ast.dump(src, include_attributes=True), + 'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), ' + 'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, ' + 'col_offset=0))' + ) + + def test_fix_missing_locations(self): + src = ast.parse('write("spam")') + src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()), + [ast.Str('eggs')], [], None, None))) + self.assertEqual(src, ast.fix_missing_locations(src)) + self.assertEqual(ast.dump(src, include_attributes=True), + "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), " + "lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, " + "col_offset=6)], keywords=[], starargs=None, kwargs=None, " + "lineno=1, col_offset=0), lineno=1, col_offset=0), " + "Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, " + "col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], " + "keywords=[], starargs=None, kwargs=None, lineno=1, " + "col_offset=0), lineno=1, col_offset=0)])" + ) + + def test_increment_lineno(self): + src = ast.parse('1 + 1', mode='eval') + self.assertEqual(ast.increment_lineno(src, n=3), src) + self.assertEqual(ast.dump(src, include_attributes=True), + 'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), ' + 'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, ' + 'col_offset=0))' + ) + + def test_iter_fields(self): + node = ast.parse('foo()', mode='eval') + d = dict(ast.iter_fields(node.body)) + self.assertEqual(d.pop('func').id, 'foo') + + #XXX: tests for equality between astlist and regular lists not + # working, breaking this test up into its components. + #self.assertEqual(d, {'keywords': [], 'kwargs': None, + # 'args': [], 'starargs': None}) + assert len(d) == 4 + assert d['keywords'] is not None + assert len(d['keywords']) == 0 + assert d['args'] is not None + assert len(d['args']) == 0 + assert d['kwargs'] is None + assert d['starargs'] is None + + def test_iter_child_nodes(self): + node = ast.parse("spam(23, 42, eggs='leek')", mode='eval') + self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4) + iterator = ast.iter_child_nodes(node.body) + self.assertEqual(iterator.next().id, 'spam') + self.assertEqual(iterator.next().n, 23) + self.assertEqual(iterator.next().n, 42) + self.assertEqual(ast.dump(iterator.next()), + "keyword(arg='eggs', value=Str(s='leek'))" + ) + + def test_get_docstring(self): + node = ast.parse('def foo():\n """line one\n line two"""') + self.assertEqual(ast.get_docstring(node.body[0]), + 'line one\nline two') + + def test_literal_eval(self): + self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3]) + self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42}) + self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None)) + self.assertRaises(ValueError, ast.literal_eval, 'foo()') + + +def test_main(): + #XXX: AST pickling is left as a TODO for now. + del AST_Tests.test_pickling + + test_support.run_unittest(AST_Tests, ASTHelpers_Test) + +def main(): + if __name__ != '__main__': + return + if sys.argv[1:] == ['-g']: + for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), + (eval_tests, "eval")): + print kind+"_results = [" + for s in statements: + print repr(to_tuple(compile(s, "?", kind, 0x400)))+"," + print "]" + print "main()" + raise SystemExit + test_main() + #### EVERYTHING BELOW IS GENERATED ##### exec_results = [ ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Pass', (1, 9))], [])]), -('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (1, 8))],[])]), +('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (1, 8))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), @@ -186,7 +315,7 @@ ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]), ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]), ('Module', [('Raise', (1, 0), ('Name', (1, 6), 'Exception', ('Load',)), ('Str', (1, 17), 'string'), None)]), -('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('excepthandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))], 3, 0)], [])]), +('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [])]), ('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]), ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]), ('Module', [('Import', (1, 0), [('alias', 'sys', None)])]), @@ -221,4 +350,4 @@ ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), ('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), ] -run_tests() +main() Property changes on: trunk/jython/ast ___________________________________________________________________ Added: svn:ignore + .asdl_antlr.py.swp Modified: trunk/jython/ast/Python.asdl =================================================================== --- trunk/jython/ast/Python.asdl 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/ast/Python.asdl 2008-12-05 01:10:49 UTC (rev 5695) @@ -1,6 +1,6 @@ -- ASDL's five builtin types are identifier, int, string, object, bool -module Python version "$Revision: 53731 $" +module Python version "$Revision: 62047 $" { mod = Module(stmt* body) | Interactive(stmt* body) @@ -10,9 +10,8 @@ | Suite(stmt* body) stmt = FunctionDef(identifier name, arguments args, - stmt* body, expr* decorators) - | ClassDef(identifier name, expr* bases, - stmt* body, expr* decorators) + stmt* body, expr* decorator_list) + | ClassDef(identifier name, expr* bases, stmt* body, expr *decorator_list) | Return(expr? value) | Delete(expr* targets) @@ -29,7 +28,8 @@ | With(expr context_expr, expr? optional_vars, stmt* body) -- 'type' is a bad name - | Raise(expr? type, expr? inst, expr? tback) + -- changed to 'type' to excepttype for Jython + | Raise(expr? excepttype, expr? inst, expr? tback) | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse) | TryFinally(stmt* body, stmt* finalbody) | Assert(expr test, expr? msg) @@ -99,11 +99,9 @@ comprehension = (expr target, expr iter, expr* ifs) -- not sure what to call the first argument for raise and except - -- TODO(jhylton): Figure out if there is a better way to handle - -- lineno and col_offset fields, particularly when - -- ast is exposed to Python. - excepthandler = (expr? type, expr? name, stmt* body, int lineno, - int col_offset) + -- changed to 'type' to excepttype for Jython + excepthandler = ExceptHandler(expr? excepttype, expr? name, stmt* body) + attributes (int lineno, int col_offset) arguments = (expr* args, identifier? vararg, identifier? kwarg, expr* defaults) Modified: trunk/jython/ast/asdl_antlr.py =================================================================== --- trunk/jython/ast/asdl_antlr.py 2008-12-05 00:26:54 UTC (rev 5694) +++ trunk/jython/ast/asdl_antlr.py 2008-12-05 01:10:49 UTC (rev 5695) @@ -9,7 +9,7 @@ import asdl TABSIZE = 4 -MAX_COL = 80 +MAX_COL = 100 def reflow_lines(s, depth): """Reflow the line s indented depth tabs. @@ -51,17 +51,39 @@ self.dir = dir super(EmitVisitor, self).__init__() - def open(self, name, refersToPythonTree=1, useDataOutput=0): - self.file = open(os.path.join(self.dir, "%s.java" % name), "w") + def open(self, package, name, refersToPythonTree=1, useDataOutput=0): + path = os.path.join(self.dir, package, "%s.java" % name) + open(path, "w") + self.file = open(os.path.join(self.dir, package, "%s.java" % name), "w") print >> self.file, "// Autogenerated AST node" - print >> self.file, 'package org.python.antlr.ast;' + print >> self.file, 'package org.python.antlr.%s;' % package if refersToPythonTree: - print >> self.file, 'import org.python.antlr.PythonTree;' print >> self.file, 'import org.antlr.runtime.CommonToken;' print >> self.file, 'import org.antlr.runtime.Token;' + print >> self.file, 'import org.python.antlr.AST;' + print >> self.file, 'import org.python.antlr.PythonTree;' + print >> self.file, 'import org.python.antlr.adapter.AstAdapters;' + print >> self.file, 'import org.python.antlr.base.excepthandler;' + print >> self.file, 'import org.python.antlr.base.expr;' + print >> self.file, 'import org.python.antlr.base.mod;' + print >> self.file, 'import org.python.antlr.base.slice;' + print >> self.file, 'import org.python.antlr.base.stmt;' + print >> self.file, 'import org.python.core.ArgParser;' + print >> self.file, 'import org.python.core.AstList;' + print >> self.file, 'import org.python.core.Py;' + print >> self.file, 'import org.python.core.PyObject;' + print >> self.file, 'import org.python.core.PyString;' + print >> self.file, 'import org.python.core.PyType;' + print >> self.file, 'import org.python.expose.ExposedGet;' + print >> self.file, 'import org.python.expose.ExposedMethod;' + print >> self.file, 'import org.python.expose.ExposedNew;' + print >> self.file, 'import org.python.expose.ExposedSet;' + print >> self.file, 'import org.python.expose.ExposedType;' + if useDataOutput: print >> self.file, 'import java.io.DataOutputStream;' print >> self.file, 'import java.io.IOException;' + print >> self.file, 'import java.util.ArrayList;' print >> self.file def close(self): @@ -131,80 +153,140 @@ self.visit(type.value, type.name, depth) def visitSum(self, sum, name, depth): - if sum.simple: + if sum.simple and not name == "excepthandler": self.simple_sum(sum, name, depth) + self.simple_sum_wrappers(sum, name, depth) else: self.sum_with_constructor(sum, name, depth) def simple_sum(self, sum, name, depth): - self.open("%sType" % name, refersToPythonTree=0) + self.open("ast", "%sType" % name, refersToPythonTree=0) self.emit('import org.python.antlr.AST;', depth) self.emit('', 0) - self.emit("public enum %(name)sType implements AST {" % locals(), depth) + + self.emit("public enum %(name)sType {" % locals(), depth) self.emit("UNDEFINED,", depth + 1) for i in range(len(sum.types) - 1): type = sum.types[i] self.emit("%s," % type.name, depth + 1) self.emit("%s;" % sum.types[len(sum.types) - 1].name, depth + 1) - self.attributes(sum, depth, True); - self.emit("}", depth) self.close() - def attributes(self, obj, depth, always_emit=False): + def simple_sum_wrappers(self, sum, name, depth): + for i in range(len(sum.types)): + type = sum.types[i] + self.open("op", type.name, refersToPythonTree=0) + self.emit('import org.python.antlr.AST;', depth) + self.emit('import org.python.antlr.PythonTree;', depth) + self.emit('import org.python.core.Py;', depth) + self.emit('import org.python.core.PyObject;', depth) + self.emit('import org.python.core.PyString;', depth) + self.emit('import org.python.core.PyType;', depth) + self.emit('import org.python.expose.ExposedGet;', depth) + self.emit('import org.python.expose.ExposedMethod;', depth) + self.emit('import org.python.expose.ExposedNew;', depth) + self.emit('import org.python.expose.ExposedSet;', depth) + self.emit('import org.python.expose.ExposedType;', depth) + self.emit('', 0) + + self.emit('@ExposedType(name = "_ast.%s", base = AST.class)' % type.name, depth) + self.emit("public class %s extends PythonTree {" % type.name, depth) + self.emit('public static final PyType TYPE = PyType.fromClass(%s.class);' % type.name, depth + 1) + self.emit('', 0) + + self.emit("public %s() {" % (type.name), depth) + self.emit("}", depth) + self.emit('', 0) + + self.emit("public %s(PyType subType) {" % (type.name), depth) + self.emit("super(subType);", depth + 1) + self.emit("}", depth) + self.emit('', 0) + + self.emit("@ExposedNew", depth) + self.emit("@ExposedMethod", depth) + self.emit("public void %s___init__(PyObject[] args, String[] keywords) {}" % type.name, depth) + self.emit('', 0) + + self.attributes(type, name, depth); + + self.emit('@ExposedMethod', depth + 1) + self.emit('public PyObject __int__() {', depth + 1) + self.emit("return %s___int__();" % type.name, depth + 2) + self.emit("}", depth + 1) + self.emit('', 0) + + self.emit("final PyObject %s___int__() {" % type.name, depth + 1) + self.emit('return Py.newInteger(%s);' % str(i + 1), depth + 2) + self.emit("}", depth + 1) + self.emit('', 0) + + self.emit("}", depth) + self.close() + + + def attributes(self, obj, name, depth): field_list = [] if hasattr(obj, "fields"): for f in obj.fields: - field_list.append('"%s"' % f.name) + field_list.append('new PyString("%s")' % f.name) if len(field_list) > 0: - self.emit("private final static String[] fields = new String[] {%s};" % - ", ".join(field_list), depth+1) - self.emit("public String[] get_fields() { return fields; }", depth+1) + self.emit("private final static PyString[] fields =", depth + 1) + self.emit("new PyString[] {%s};" % ", ".join(field_list), depth+1) + self.emit('@ExposedGet(name = "_fields")', depth + 1) + self.emit("public PyString[] get_fields() { return fields; }", depth+1) self.emit("", 0) - elif always_emit: - self.emit("private final static String[] fields = new String[0];", depth+1) - self.emit("public String[] get_fields() { return fields; }", depth+1) + else: + self.emit("private final static PyString[] fields = new PyString[0];", depth+1) + self.emit('@ExposedGet(name = "_fields")', depth + 1) + self.emit("public PyString[] get_fields() { return fields; }", depth+1) self.emit("", 0) - att_list = [] - if hasattr(obj, "attributes"): - for a in obj.attributes: - att_list.append('"%s"' % a.name) - if len(att_list) > 0: - self.emit("private final static String[] attributes = new String[] {%s};" % - ", ".join(att_list), depth+1) - self.emit("public String[] get_attributes() { return attributes; }", depth+1) + if str(name) in ('stmt', 'expr', 'excepthandler'): + att_list = ['new PyString("lineno")', 'new PyString("col_offset")'] + self.emit("private final static PyString[] attributes =", depth + 1) + self.emit("new PyString[] {%s};" % ", ".join(att_list), depth + 1) + self.emit('@ExposedGet(name = "_attributes")', depth + 1) + self.emit("public PyString[] get_attributes() { return attributes; }", depth + 1) self.emit("", 0) - elif always_emit: - self.emit("private final static String[] attributes = new String[0];", depth+1) - self.emit("public String[] get_attributes() { return attributes; }", depth+1) + else: + self.emit("private final static PyString[] attributes = new PyString[0];", depth+1) + self.emit('@ExposedGet(name = "_attributes")', depth + 1) + self.emit("public PyString[] get_attributes() { return attributes; }", depth+1) self.emit("", 0) def sum_with_constructor(self, sum, name, depth): - self.open("%sType" % name) + self.open("base", "%s" % name) - self.emit("public abstract class %(name)sType extends PythonTree {" % + self.emit('@ExposedType(name = "_ast.%s", base = AST.class)' % name, depth) + self.emit("public abstract class %(name)s extends PythonTree {" % locals(), depth) self.emit("", 0) + self.emit("public static final PyType TYPE = PyType.fromClass(%s.class);" % name, depth + 1); - self.attributes(sum, depth); + self.attributes(sum, name, depth); - self.emit("public %(name)sType() {" % locals(), depth+1) + self.emit("public %(name)s() {" % locals(), depth+1) self.emit("}", depth+1) self.emit("", 0) - self.emit("public %(name)sType(int ttype, Token token) {" % locals(), depth+1) + self.emit("public %(name)s(PyType subType) {" % locals(), depth+1) + self.emit("}", depth+1) + self.emit("", 0) + + self.emit("public %(name)s(int ttype, Token token) {" % locals(), depth+1) self.emit("super(ttype, token);", depth+2) self.emit("}", depth+1) self.emit("", 0) - self.emit("public %(name)sType(Token token) {" % locals(), depth+1) + self.emit("public %(name)s(Token token) {" % locals(), depth+1) self.emit("super(token);", depth+2) self.emit("}", depth+1) self.emit("", 0) - self.emit("public %(name)sType(PythonTree node) {" % locals(), depth+1) + self.emit("public %(name)s(PythonTree node) {" % locals(), depth+1) self.emit("super(node);", depth+2) self.emit("}", depth+1) self.emit("", 0) @@ -216,22 +298,24 @@ def visitProduct(self, product, name, depth): - self.open("%sType" % name, useDataOutput=1) - self.emit("public class %(name)sType extends PythonTree {" % locals(), depth) + self.open("ast", "%s" % name, useDataOutput=1) + self.emit('@ExposedType(name = "_ast.%s", base = AST.class)' % name, depth) + self.emit("public class %(name)s extends PythonTree {" % locals(), depth) + self.emit("public static final PyType TYPE = PyType.fromClass(%s.class);" % name, depth + 1); for f in product.fields: self.visit(f, depth + 1) self.emit("", depth) - self.attributes(product, depth) + self.attributes(product, name, depth) - self.javaMethods(product, name, "%sType" % name, product.fields, + self.javaMethods(product, name, "%s" % name, product.fields, depth+1) self.emit("}", depth) self.close() def visitConstructor(self, cons, name, depth): - self.open(cons.name, useDataOutput=1) + self.open("ast", cons.name, useDataOutput=1) ifaces = [] for f in cons.fields: if str(f.type) == "expr_context": @@ -240,13 +324,15 @@ s = "implements %s " % ", ".join(ifaces) else: s = "" - self.emit("public class %s extends %sType %s{" % + self.emit('@ExposedType(name = "_ast.%s", base = AST.class)' % cons.name, depth); + self.emit("public class %s extends %s %s{" % (cons.name, name, s), depth) + self.emit("public static final PyType TYPE = PyType.fromClass(%s.class);" % cons.name, depth); for f in cons.fields: self.visit(f, depth + 1) self.emit("", depth) - self.attributes(cons, depth) + self.attributes(cons, name, depth) self.javaMethods(cons, cons.name, cons.name, cons.fields, depth+1) @@ -256,9 +342,10 @@ self.emit("}", depth + 1) self.emit("", 0) - if str(name) in ('stmt', 'expr'): + if str(name) in ('stmt', 'expr', 'excepthandler'): # The lineno property self.emit("private int lineno = -1;", depth + 1) + self.emit('@ExposedGet(name = "lineno")', depth + 1) self.emit("public int getLineno() {", depth + 1) self.emit("if (lineno != -1) {", depth + 2); self.emit("return lineno;", depth + 3); @@ -266,6 +353,7 @@ self.emit('return getLine();', depth + 2) self.emit("}", depth + 1) self.emit("", 0) + self.emit('@ExposedSet(name = "lineno")', depth + 1) self.emit("public void setLineno(int num) {", depth + 1) self.emit("lineno = num;", depth + 2); self.emit("}", depth + 1) @@ -273,6 +361,7 @@ # The col_offset property self.emit("private int col_offset = -1;", depth + 1) + self.emit('@ExposedGet(name = "col_offset")', depth + 1) self.emit("public int getCol_offset() {", depth + 1) self.emit("if (col_offset != -1) {", depth + 2); self.emit("return col_offset;", depth + 3); @@ -280,75 +369,49 @@ self.emit('return getCharPositionInLine();', depth + 2) self.emit("}", depth + 1) self.emit("", 0) + self.emit('@ExposedSet(name = "col_offset")', depth + 1) self.emit("public void setCol_offset(int num) {", depth + 1) self.emit("col_offset = num;", depth + 2); self.emit("}", depth + 1) self.emit("", 0) + self.emit("}", depth) self.close() def javaConstructorHelper(self, fields, depth): for f in fields: + #if f.seq: + # self.emit("this.%s = new %s(%s);" % (f.name, + # self.javaType(f), f.name), depth+1) + #else: self.emit("this.%s = %s;" % (f.name, f.name), depth+1) + fparg = self.fieldDef(f) - #if field.typedef and field.typedef.simple: + not_simple = True if f.typedef is not None and f.typedef.simple: not_simple = False #For now ignoring String -- will want to revisit - if not_simple and not fparg.startswith("String"): + if not_simple and fparg.find("String") == -1: if f.seq: - self.emit("if (%s != null) {" % f.name, depth+1); - self.emit("for(int i%(name)s=0;i%(name)s<%(name)s.length;i%(name)s++) {" % {"name":f.name}, depth+2) - self.emit("addChild(%s[i%s]);" % (f.name, f.name), depth+3) - self.emit("}", depth+2) + self.emit("if (%s == null) {" % f.name, depth+1); + self.emit("this.%s = new ArrayList<%s>();" % (f.name, self.javaType(f, False)), depth+2) self.emit("}", depth+1) + self.emit("for(PythonTree t : this.%(name)s) {" % {"name":f.name}, depth+1) + self.emit("addChild(t);", depth+2) + self.emit("}", depth+1) elif str(f.type) == "expr": self.emit("addChild(%s);" % (f.name), depth+1) #XXX: this method used to emit a pickle(DataOutputStream ostream) for cPickle support. # If we want to re-add it, see Jython 2.2's pickle method in its ast nodes. def javaMethods(self, type, clsname, ctorname, fields, depth): - # The java ctors - fpargs = ", ".join([self.fieldDef(f) for f in fields]) - self.emit("public %s(%s) {" % (ctorname, fpargs), depth) - self.javaConstructorHelper(fields, depth) - self.emit("}", depth) - self.emit("", 0) + self.javaConstructors(type, clsname, ctorname, fields, depth) - token = asdl.Field('Token', 'token') - token.typedef = False - fpargs = ", ".join([self.fieldDef(f) for f in [token] + fields]) - self.emit("public %s(%s) {" % (ctorname, fpargs), depth) - self.emit("super(token);", depth+1) - self.javaConstructorHelper(fields, depth) - self.emit("}", depth) - self.emit("", 0) - - ttype = asdl.Field('int', 'ttype') - ttype.typedef = False - fpargs = ", ".join([self.fieldDef(f) for f in [ttype, token] + fields]) - self.emit("public %s(%s) {" % (ctorname, fpargs), depth) - self.emit("super(ttype, token);", depth+1) - self.javaConstructorHelper(fields, depth) - self.emit("}", depth) - self.emit("", 0) - - tree = asdl.Field('PythonTree', 'tree') - tree.typedef = False - fpargs = ", ".join([self.fieldDef(f) for f in [tree] + fields]) - self.emit("public %s(%s) {" % (ctorname, fpargs), depth) - self.emit("super(tree);", depth+1) - self.javaConstructorHelper(fields, depth) - self.emit("}", depth) - self.emit("", 0) - - if fpargs: - fpargs += ", " - # The toString() method + self.emit('@ExposedGet(name = "repr")', depth) self.emit("public String toString() {", depth) self.emit('return "%s";' % clsname, depth+1) self.emit("}", depth) @@ -386,10 +449,10 @@ continue if f.seq: self.emit('if (%s != null) {' % f.name, depth+1) - self.emit('for (int i = 0; i < %s.length; i++) {' % f.name, + self.emit('for (PythonTree t : %s) {' % f.name, depth+2) - self.emit('if (%s[i] != null)' % f.name, depth+3) - self.emit('%s[i].accept(visitor);' % f.name, depth+4) + self.emit('if (t != null)', depth+3) + self.emit('t.accept(visitor);', depth+4) self.emit('}', depth+2) self.emit('}', depth+1) else: @@ -398,26 +461,131 @@ self.emit('}', depth) self.emit("", 0) + def javaConstructors(self, type, clsname, ctorname, fields, depth): + if len(fields) > 0: + self.emit("public %s() {" % (ctorname), depth) + self.emit("this(TYPE);", depth + 1) + self.emit("}", depth) + + self.emit("public %s(PyType subType) {" % (ctorname), depth) + self.emit("super(subType);", depth + 1) + self.emit("}", depth) + + fpargs = ", ".join(['"%s"' % f.name for f in fields]) + self.emit("@ExposedNew", depth) + self.emit("@ExposedMethod", depth) + self.emit("public void %s___init__(PyObject[] args, String[] keywords) {" % ctorname, depth) + self.emit('ArgParser ap = new ArgParser("%s", args, keywords, new String[]' % ctorname, depth + 1) + self.emit('{%s}, %s);' % (fpargs, len(fields)), depth + 2) + i = 0 + for f in fields: + self.emit("set%s(ap.getPyObject(%s));" % (str(f.name).capitalize(), + str(i)), depth+1) + i += 1 + self.emit("}", depth) + self.emit("", 0) + + fpargs = ", ".join(["PyObject %s" % f.name for f in fields]) + self.emit("public %s(%s) {" % (ctorname, fpargs), depth) + for f in fields: + self.emit("set%s(%s);" % (str(f.name).capitalize(), + f.name), depth+1) + self.emit("}", depth) + self.emit("", 0) + + token = asdl.Field('Token', 'token') + token.typedef = False + fpargs = ", ".join([self.fieldDef(f) for f in [token] + fields]) + self.emit("public %s(%s) {" % (ctorname, fpargs), depth) + self.emit("super(token);", depth+1) + self.javaConstructorHelper(fields, depth) + self.emit("}", depth) + self.emit("", 0) + + ttype = asdl.Field('int', 'ttype') + ttype.typedef = False + fpargs = ", ".join([self.fieldDef(f) for f in [ttype, token] + fields]) + self.emit("public %s(%s) {" % (ctorname, fpargs), depth) + self.emit("super(ttype, token);", depth+1) + self.javaConstructorHelper(fields, depth) + self.emit("}", depth) + self.emit("", 0) + + tree = asdl.Field('PythonTree', 'tree') + tree.typedef = False + fpargs = ", ".join([self.fieldDef(f) for f in [tree] + fields]) + self.emit("public %s(%s) {" % (ctorname, fpargs), depth) + self.emit("super(tree);", depth+1) + self.javaConstructorHelper(fields, depth) + self.emit("}", depth) + self.emit("", 0) + + def visitField(self, field, depth): - self.emit("public %s;" % self.fieldDef(field), depth) + self.emit("private %s;" % self.fieldDef(field), depth) + self.emit("public %s getInternal%s() {" % (self.javaType(field), + str(field.name).capitalize()), depth) + self.emit("return %s;" % field.name, depth+1) + self.emit("}", depth) + self.emit('@ExposedGet(name = "%s")' % field.name, depth) + self.emit("public PyObject get%s() {" % (str(field.name).capitalize()), depth) + if field.seq: + self.emit("return new AstList(%s, AstAdapters.%sAdapter);" % (field.name, field.type), depth+1) + else: + if str(field.type) == 'identifier': + self.emit("if (%s == null) return Py.None;" % field.name, depth+1) + self.emit("return new PyString(%s);" % field.name, depth+1) + elif str(field.type) == 'string' or str(field.type) == 'object': + self.emit("return (PyObject)%s;" % field.name, depth+1) + elif str(field.type) == 'bool': + self.emit("if (%s) return Py.True;" % field.name, depth+1) + self.emit("return Py.False;" % field.name, depth+1) + elif str(field.type) == 'int': + self.emit("return Py.newInteger(%s);" % field.name, depth+1) + elif field.typedef.simple: + self.emit("return AstAdapters.%s2py(%s);" % (str(field.type), field.name), depth+1) + else: + self.emit("return %s;" % field.name, depth+1) + #self.emit("return Py.None;", depth+1) + self.emit("}", depth) + self.emit('@ExposedSet(name = "%s")' % field.name, depth) + self.emit("public void set%s(PyObject %s) {" % (str(field.name).capitalize(), + field.name), depth) + if field.seq: + #self.emit("this.%s = new %s(" % (field.name, self.javaType(field)), depth+1) + self.emit("this.%s = AstAdapters.py2... [truncated message content] |