Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 311201

Summary: [compiler] hasRole(Object, Class) call in inner teams ends up in NoSuchMethodError
Product: [Tools] Objectteams Reporter: Jan Marc Hoffmann <exelnet>
Component: OTJAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED FIXED QA Contact:
Severity: major    
Priority: P3 CC: stephan.herrmann
Version: 1.4Flags: stephan.herrmann: iplog+
Target Milestone: 0.7 M2   
Hardware: PC   
OS: All   
Whiteboard:
Attachments:
Description Flags
patch none

Description Jan Marc Hoffmann CLA 2010-04-30 12:02:09 EDT
The call of the hasRole(Object, Class) method throws a NoSuchMethodError if the call is used in an inner team.

Code to reproduce the bug:

public team class OuterTeam {
	
	public team class InnerTeam playedBy OuterBase {
	
		protected class SomeRole playedBy InnerBase {
		}
		
		@SuppressWarnings("ambiguouslowering")
		public void createRole(InnerBase as SomeRole b) {
			System.out.println(OuterTeam.this.hasRole(b, SomeRole.class));
		}	
	}
	
	public InnerTeam registerInnerTeam(OuterBase as InnerTeam o) {
		return o;
	}
}

public class Main {

	public static void main(String[] args) {
		OuterBase ob = new OuterBase();
		InnerBase ib = new InnerBase();
		final OuterTeam ot = new OuterTeam();
		InnerTeam<@ot> it = ot.registerInnerTeam(ob);
		it.createRole(ib);
	}
}
Comment 1 Stephan Herrmann CLA 2010-04-30 17:31:26 EDT
Thanks for the report.

BTW: why did you suppress the warning?
I think it has something relevant to tell, no?
Comment 2 Stephan Herrmann CLA 2010-05-01 06:27:00 EDT
Created attachment 166716 [details]
patch

Fixed: for nested teams we have to ensure that the synthetic _OT$getClass$XY
method is also propagated into the interface part. In the example we were only 
generating
  otdtbugs.OuterTeam$__OT__InnerTeam._OT$getClass$SomeRole() {...}
not
  otdtbugs.OuterTeam$InnerTeam._OT$getClass$SomeRole();
Comment 3 Stephan Herrmann CLA 2010-05-01 06:32:39 EDT
Patch committed as part of r274.

Tests are test926_roleClassLiteralAccess3() and test926_roleClassLiteralAccess4()
Comment 4 Stephan Herrmann CLA 2010-05-06 10:17:08 EDT
Verified for M2 using I201005052210

In order to successfully run the example I change OuterTeam to:

public team class OuterTeam {

    public team class InnerTeam playedBy OuterBase {

        protected class SomeRole extends Confined playedBy InnerBase {
        }

        public void createRole(InnerBase as SomeRole b) {
            System.out.println(InnerTeam.this.hasRole(b, SomeRole.class));
        }    
    }

    public InnerTeam registerInnerTeam(OuterBase as InnerTeam o) {
        return o;
    }
}

By marking SomeRole as Confined I ensure that hasRole(b, ...) will need
to lower its argument b because Object is expected, which SomeRole no longer
is conform to. This also resolves the "ambiguouslowering" warning.
Additionally, the InnerTeam must be asked not OuterTeam.
(Note, that the argument to hasRole must be a base instance).
Comment 5 Jan Marc Hoffmann CLA 2010-05-10 08:16:57 EDT
(In reply to comment #1)
> Thanks for the report.
> 
> BTW: why did you suppress the warning?
> I think it has something relevant to tell, no?

Oh yeah it has. I have just been copying this code and modified it quick to a simple example. I didn't read the warning carefully at that time. 

It's ambiguous because both the base and the role inherit Object. So the lowering mechanism doesn't know what to do. Makes sense. Thanks for pointing it out.

greetings 
Jan Marc
Comment 6 Stephan Herrmann CLA 2011-05-10 09:14:11 EDT
Setting iplog flag to acknowledge the contributed testcase in comment 0.