java2python icon indicating copy to clipboard operation
java2python copied to clipboard

lengthToLen() is called when the selection pattern doesn't fully match

Open rcludwick opened this issue 13 years ago • 3 comments

So part of tracking down the length issue (since I'm seeing that currently), I noticed that the call transforms.lengthToLen() got called repeatedly for transforms that weren't related to the selection definition for that function.

Breaking in with the python debugger gave me the following:

In compiler/__init__.py(38):transformAST()
-> import pdb; pdb.set_trace()
(Pdb) print selector
Child(Type(DOT:15) > Type(IDENT=length:164))

There should be a METHOD_CALL in front of that according to what's in config/default.py:

(Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'), transform.lengthToLen)

Further tracing shows the problem to be in the Selector.gt() function in lang/selector.py:

def __gt__(self, other):
    """ E > F

    Like CSS: "E > F": an F element child of an E element
    """
    return Child(self, other)

In the case of Type(A) > Type(B) > Type(C), the interpreter is evaluating Type(A) > Type(B) as True first and then returns the value of Type(B) > Type(C).

rcludwick avatar May 21 '12 01:05 rcludwick

I'm thinking that one option might be to override the >> op instead, but I'm trying to think if there's a left to right issue.

Ideally, for Type(A) >> Type(B) >> Type(C) I think I'd want:

Child(Type(A), Child(Type(B), Type(C)))

But right now, I'd get:

Child(Child(Type(A), Type(B)), Type(C))

Are those equivalent selections?

rcludwick avatar May 21 '12 03:05 rcludwick

Thanks for the detailed analysis and ticket. That's truly appreciated.

I think the selector is wrong; the Type('METHOD_CALL') doesn't need to be in there at all.

I checked the __gt__ issue, and it works like I expect in a test case that's outside of j2py, so I'll revisit that when I'm wrapping this up.

natural avatar May 21 '12 15:05 natural

Here's the source file I was concentrating on, and it could serve as a good test case for the conversion of length to len():

http://code.google.com/p/zxing/source/browse/trunk/core/src/com/google/zxing/common/reedsolomon/GenericGFPoly.java

When I ran j2py against that, j2py crashed.

The AST being passed into lengthToLen didn't resemble the AST lengthToLen is expecting in it's docstring.

This is the code I tested to test the gt()


class A(object):
    def __gt__(self, other):
        print str(self.__class__) + "__gt__() called"
        return self

class B(A):
    pass

class C(A):
    pass

class D(A):
    pass


result = A() > B() > C() > D()
print "Output: " + str(result.__class__)

result = A() > ( B() > ( C() > D() ) )
print "Output: " + str(result.__class__)

The output looks like this:

<class '__main__.A'>__gt__() called
<class '__main__.B'>__gt__() called
<class '__main__.C'>__gt__() called
Output: <class '__main__.C'>
<class '__main__.C'>__gt__() called
<class '__main__.B'>__gt__() called
<class '__main__.A'>__gt__() called
Output: <class '__main__.A'>

This the exact behavior I saw with the selector. In the first case, whatever A and B returns are tossed. Parens are added to force the correct behavior in the second case.

rcludwick avatar May 21 '12 18:05 rcludwick