Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"ghost" type parameter in field #33

Closed
web-online opened this issue Sep 22, 2016 · 2 comments
Closed

"ghost" type parameter in field #33

web-online opened this issue Sep 22, 2016 · 2 comments

Comments

@web-online
Copy link

web-online commented Sep 22, 2016

I have found an issue that at first I thought was related to Issue #28 but is specific to fields so maybe is different. I've pasted a test showing the issue below:

package com.fasterxml.classmate.members;

import java.util.List;

import junit.framework.TestCase;

import com.fasterxml.classmate.*;
import java.math.BigInteger;

// for issue "ghost" type parameter in field:
public class GhostTypeParameterInFieldTest
    extends TestCase
{
    public static class A<T extends Number> {
        public Integer i;
        public BigInteger bigI;
    }

    ResolvedField[] fields;

    @Override
    protected void setUp() throws Exception {
        TypeResolver resolver = new TypeResolver();
        ResolvedType resolvedType = resolver.resolve(A.class, Integer.class);
        MemberResolver memberResolver = new MemberResolver(resolver);
        ResolvedTypeWithMembers resolvedTypeWithMembers = memberResolver.resolve(resolvedType, null, null);
        fields = resolvedTypeWithMembers.getMemberFields();
    }

    public void testPrimitive()
    {
        // test fields
        assertEquals(2, fields.length);

        // field Integer i
        ResolvedField iField = fields[0];
        assertEquals("i", iField.getName());
        ResolvedType iArg = iField.getType();
        assertEquals(Integer.class, iArg.getErasedType());
        assertTrue("i should be a primitive", iArg.isPrimitive());

        // field BigInteger bigI 
        ResolvedField bigIField = fields[1];
        assertEquals("bigI", bigIField.getName());
        ResolvedType bigIArg = bigIField.getType();
        assertEquals(BigInteger.class, bigIArg.getErasedType());
        assertFalse("bigI should not be a primitive", bigIArg.isPrimitive());
    }

    public void testGhostTypeParameterInField()
    {
        // test fields
        assertEquals(2, fields.length);

        // field Integer i
        ResolvedField iField = fields[0];
        assertEquals("i", iField.getName());
        ResolvedType iArg = iField.getType();
        assertEquals(Integer.class, iArg.getErasedType());
        List<ResolvedType> iTypeParams = iArg.getTypeParameters();
        if (iTypeParams.size() != 0) {
            fail("Expected 0 type parameters for Integer i, got "+iTypeParams.size()+": "+iTypeParams);
        }

        // field BigInteger bigI 
        ResolvedField bigIField = fields[1];
        assertEquals("bigI", bigIField.getName());
        ResolvedType bigIArg = bigIField.getType();
        assertEquals(BigInteger.class, bigIArg.getErasedType());
        List<ResolvedType> bigITypeParams = bigIArg.getTypeParameters();
        if (bigITypeParams.size() != 0) {
            fail("Expected 0 type parameters for BigInteger bigI, got "+bigITypeParams.size()+": "+bigITypeParams);
        }
    }

}

This fails with

Failed tests: 
  GhostTypeParameterInFieldTest.testPrimitive:40 i should be a primitive
  GhostTypeParameterInFieldTest.testGhostTypeParameterInField:62 Expected 0 type parameters for Integer i, got 1: [java.lang.Integer]

Assuming this is a real problem, I think I've traced it to TypeResolver._fromClass. There may be multiple things going on here, but here are my two suspicions:

  • The Integer type should be a primitive but the ClassKey that is built for Integer.class is not matching on line 339
  • The type construction is incorrectly associating the type bindings to the Integer type (resulting in an Integer with a parameterized type) on line 368

(accidentally pasted in the wrong test before. edited with correct test that also uses static inner class and tests both for primitive and "ghost" parameters)

@cowtowncoder
Copy link
Member

Thank you for reporting this. Does indeed sound like a bug of some kinds. The only other interesting part is whether it could be related to this being a non-static inner class; those have the hidden this parameter for many things. But I don't see how that could lead to issues with field types, so probably that is not relevant here.

web-online pushed a commit to web-online/java-classmate that referenced this issue Sep 27, 2016
cowtowncoder added a commit that referenced this issue Sep 28, 2016
test and fix for issue #33: "ghost" type parameter in field
cowtowncoder added a commit that referenced this issue Sep 28, 2016
@web-online
Copy link
Author

confirmed fixed in 1.3.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants