Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.2Release
    • Fix Version/s: 2.5.0Release
    • Component/s: Inferencing Engine
    • Labels:
      None
    • Number of attachments :
      0

      Description

      In the snippet below, MyMap.get() should be inferred as the get() method on WeakReference, but it isn't.

      //@Typed
      class RemoteMessageChannel<M extends Serializable> {// extends MessageChannel<M> {
      
      //	static class MyMap<K,V> extends HashMap<K,WeakReference<V>> {
      	
      	static class MyMap extends HashMap<String,WeakReference<Class>> {	
      //		V putIfNotYet(K key, V value) {
      			
      	
      //		}
      	}
      	MyMap cache;
      	
      	void receiveBytes(String name) {
      		ClassLoader parent
      		if (name == this.class.name)
      			this.class
      		else { 
      			def res = cache.get(name)?.get()
      			if (res == this.class)
      				throw new ClassNotFoundException()
      			if (!res) {
      				try {
      					res = parent.loadClass(name)
      				}
      				catch (ClassNotFoundException e) {
      					cache.putIfNotYet(name, this.class)
      					throw e
      				}
      				cache.putIfNotYet(name, res)
      			}
      //			return res
      		}
      	}
      	
      }
      

        Activity

        Hide
        Andrew Eisenberg added a comment -

        Here is a simpler variant of the problem:

        
        class MyMap extends HashMap<String,WeakReference<Class>> {	 }
        MyMap cache;
        
        HashMap<String,WeakReference<Class>> other
        
        cache.get(name).get()  // underlined
        other.get(name).get()  // not underlined
        
        Show
        Andrew Eisenberg added a comment - Here is a simpler variant of the problem: class MyMap extends HashMap< String ,WeakReference< Class >> { } MyMap cache; HashMap< String ,WeakReference< Class >> other cache.get(name).get() // underlined other.get(name).get() // not underlined
        Hide
        Andrew Eisenberg added a comment -

        Even simpler:

        class MyMap extends HashMap<String,Class> {	 }
        MyMap cache;
        cache.get("")
        

        The problem is that the GenericsNode}}s on the ClassNode for the cache variable's declaration is null and references to methods on HashMap that should know about the type parameters do not have them resolved. However, when looking at {{HashMap, the type parameters are placed correctly.

        What I think needs to happen is that some better awareness of Generics are required for the inferencing engine. Currently, the inferencing engine assumes that all type parameters are declared in the lowest level type and instanciated in the variable declaration. This solves the common case like this:

        List<String> foo
        

        However, when the type variables are instantiated in a subtype and a variable is declared without direct mention of the type variable (as in the example), the inferencing engine cannot find the type variable and so assumes that no generic types are involved.

        We need to ensure that the inferencing engine knows about all type variables an how they are instantiated.

        Show
        Andrew Eisenberg added a comment - Even simpler: class MyMap extends HashMap< String , Class > { } MyMap cache; cache.get("") The problem is that the GenericsNode}}s on the ClassNode for the cache variable's declaration is null and references to methods on HashMap that should know about the type parameters do not have them resolved. However, when looking at {{HashMap , the type parameters are placed correctly. What I think needs to happen is that some better awareness of Generics are required for the inferencing engine. Currently, the inferencing engine assumes that all type parameters are declared in the lowest level type and instanciated in the variable declaration. This solves the common case like this: List< String > foo However, when the type variables are instantiated in a subtype and a variable is declared without direct mention of the type variable (as in the example), the inferencing engine cannot find the type variable and so assumes that no generic types are involved. We need to ensure that the inferencing engine knows about all type variables an how they are instantiated.
        Hide
        Andrew Eisenberg added a comment -

        See SimpleTypeLookup.typeFromDeclaration().

        Show
        Andrew Eisenberg added a comment - See SimpleTypeLookup.typeFromDeclaration() .
        Hide
        Andrew Eisenberg added a comment -

        Progress...I have something working in my workspace. The logic to capture all generics is very tricky. I'll need to write lots of tests before I can commit.

        Show
        Andrew Eisenberg added a comment - Progress...I have something working in my workspace. The logic to capture all generics is very tricky. I'll need to write lots of tests before I can commit.
        Hide
        Andrew Eisenberg added a comment -

        No...my solution isn't quite right. When subclasses partially resolve the type parameters of the super class, such as the example originally supplied in this bug report, my current solution isn't working right.

        Show
        Andrew Eisenberg added a comment - No...my solution isn't quite right. When subclasses partially resolve the type parameters of the super class, such as the example originally supplied in this bug report, my current solution isn't working right.
        Hide
        Andrew Eisenberg added a comment -

        Wow. This turned out to be a lot more difficult than I had originally thought. I had to completely rewrite the generics resolver code. The good news is that it is less complicated now (even though I am still not happy with it), and also it is more complete.

        I am committing this work now with a bunch more tests for it.

        Show
        Andrew Eisenberg added a comment - Wow. This turned out to be a lot more difficult than I had originally thought. I had to completely rewrite the generics resolver code. The good news is that it is less complicated now (even though I am still not happy with it), and also it is more complete. I am committing this work now with a bunch more tests for it.

          People

          • Assignee:
            Andrew Eisenberg
            Reporter:
            Andrew Eisenberg
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: