Bug 405043 - Support stateful traits with extension to JDK 1.8 default interface method syntax
Summary: Support stateful traits with extension to JDK 1.8 default interface method sy...
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-04-05 17:03 EDT by Matthew Adams CLA
Modified: 2013-04-05 17:03 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Adams CLA 2013-04-05 17:03:22 EDT
With Java 1.8's introduction of default interface methods, it will have arrived at support for stateless traits.  Stateful traits, OTOH, aren't yet supported, unless you use the pattern described as follows, which theoretically works from JDK 1.5+ and the current 1.7.x version of aspectj (barring some pending pointcut matching enhancements).

First, define an interface that describes the behavior:

package org.example.traits;

public interface Nameable {
    String getName();
    void setName(String name);
}

Next, define an annotation that can be used to drive introduction:

package org.example.traits;

@Target(TYPE)
@Retention(RUNTIME)
public @interface Expresses {
    Class[] value();
}

Next, define an aspect that provides an implementation of the behavior:

package org.example.traits;

public privileged aspect NameableAspect {

	public interface I extends Nameable {
 	}

	declare parents : (@Expresses(..,Nameable.class,..) *) implements I;

	private String I.name;

 	public void I.setName(String name) {
		this.name = name;
 	}

 	public String I.getName() {
 		return name;
	}
}

Last, annotate a class that needs to receive the ITD:

package org.example.domain;

// imports...

@Expresses(Nameable.class)
public class Person {
}

I think this is fodder for post-Java 1.8; if AspectJ is revving to 2.0 for that release, this seems like a suitable to me to add this support.

This trait, if defined using the JDK 1.8 syntax (currently proposed as of this writing), could look like the following:

package org.example.traits;

public interface Nameable {

    default String name; // new

    default void setName(String name) {
        this.name = name; // new: accesses state
    }

    default String getName() {
        return name; // new: accesses state
    }
}

Then, any class declaring that it implements Nameable would get the default methods and fields.  This could even be backported by aspectj to JDK 1.7-.  Override semantics would still need to be worked out, but I think this would work pretty cleanly.

See discussion at http://aspectj.2085585.n4.nabble.com/Trait-syntax-sugar-tt4650566.html.