aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2014-05-08 06:25:38 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2014-05-20 23:43:08 +0200
commit4996428ea12be7e381d76614e34a15ad1cc6d275 (patch)
treeca5067b7b8f63eff6adeed83f8ff9339128d8ca7
parent05ca21b75e5c20e1e731d9141857f346bb3eca9f (diff)
downloadlombok-4996428ea12be7e381d76614e34a15ad1cc6d275.tar.gz
lombok-4996428ea12be7e381d76614e34a15ad1cc6d275.tar.bz2
lombok-4996428ea12be7e381d76614e34a15ad1cc6d275.zip
@Delegate has moved to lombok.experimental.
Some work on the aliasing system to make that go smoothly.
-rw-r--r--doc/changelog.markdown2
-rw-r--r--src/core/lombok/Delegate.java18
-rw-r--r--src/core/lombok/core/LombokInternalAliasing.java20
-rw-r--r--src/core/lombok/eclipse/EclipseImportList.java14
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java2
-rw-r--r--src/core/lombok/experimental/Delegate.java64
-rw-r--r--src/core/lombok/javac/JavacImportList.java19
-rw-r--r--src/core/lombok/javac/handlers/HandleDelegate.java6
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java2
-rw-r--r--website/features/Log.html2
-rw-r--r--website/features/experimental/Delegate.html (renamed from website/features/Delegate.html)55
-rw-r--r--website/features/experimental/FieldDefaults.html2
-rw-r--r--website/features/experimental/Wither.html2
-rw-r--r--website/features/experimental/index.html2
-rw-r--r--website/features/index.html2
15 files changed, 148 insertions, 64 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 10fedb75..b49f6de8 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,9 +2,11 @@ Lombok Changelog
----------------
### v1.12.7 "Edgy Guinea Pig"
+* DEPRECATION: `@Delegate` has been moved to `lombok.experimental.Delegate`, and corner cases such as recursive delegation (delegating a type that itself has fields or methods annotated with `@Delegate`) are now error conditions. See the [feature documentation](http://projectlombok.org/features/experimental/Delegate.html) for more information.
* FEATURE: It is now possible to put annotations, such as `@Nullable`, on the one parameter of generated `equals()` methods by specifying the `onParam=` option on `@EqualsAndHashCode`, similar to how that feature already exists for `@Setter`. [Issue #674](https://code.google.com/p/projectlombok/issues/detail?id=674)
* CHANGE: suppressConstructorProperties should now be configured via lombok configuration. [Issue #659](https://code.google.com/p/projectlombok/issues/detail?id=659)
* CHANGE: The `canEqual` method generated by `@EqualsAndHashCode`, `@Value` and `@Data` is now `protected` instead of `public`. [Issue #660](https://code.google.com/p/projectlombok/issues/detail?id=660)
+* BUGFIX: Major work on improving support for JDK8, both for javac and eclipse.
* BUGFIX: Deadlocks would occasionally occur in eclipse when using lazy getters [Issue #590](https://code.google.com/p/projectlombok/issues/detail?id=590)
* BUGFIX: Usage of `@SneakyThrows` with a javac from JDK8 with `-target 1.8` would result in a post compiler error. [Issue #655](https://code.google.com/p/projectlombok/issues/detail?id=655)
* BUGFIX: Switching workspace on some versions of eclipse resulted in a 'duplicate field' error. [Issue #666](https://code.google.com/p/projectlombok/issues/detail?id=666)
diff --git a/src/core/lombok/Delegate.java b/src/core/lombok/Delegate.java
index 534cfb3d..d5b4b48c 100644
--- a/src/core/lombok/Delegate.java
+++ b/src/core/lombok/Delegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 The Project Lombok Authors.
+ * Copyright (C) 2010-2014 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,23 +27,11 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Put on any field to make lombok generate delegate methods that forward the call to this field.
- *
- * Example:
- * <pre>
- * private &#64;Delegate List&lt;String&gt; foo;
- * </pre>
- *
- * will generate for example an {@code boolean add(String)} method, which contains: {@code return foo.add(arg);}, as well as all other methods in {@code List}.
- *
- * All public instance methods of the field's type, as well as all public instance methods of all the field's type's superfields are delegated, except for all methods
- * that exist in {@link Object}, the {@code canEqual(Object)} method, and any methods that appear in types
- * that are listed in the {@code excludes} property.
- * <p>
- * Complete documentation is found at <a href="http://projectlombok.org/features/Delegate.html">the project lombok features page for &#64;Delegate</a>.
+ * @deprecated Use {@link lombok.experimental.Delegate} instead.
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
+@Deprecated
public @interface Delegate {
/**
* Normally the type of the field is used as delegate type. However, to choose a different type to delegate, you can list one (or more) types here. Note that types with
diff --git a/src/core/lombok/core/LombokInternalAliasing.java b/src/core/lombok/core/LombokInternalAliasing.java
index 4fd7b29d..8d6794ae 100644
--- a/src/core/lombok/core/LombokInternalAliasing.java
+++ b/src/core/lombok/core/LombokInternalAliasing.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Project Lombok Authors.
+ * Copyright (C) 2013-2014 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,12 +21,14 @@
*/
package lombok.core;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class LombokInternalAliasing {
- public static final Map<String, String> IMPLIED_EXTRA_STAR_IMPORTS;
+ /** Maps a package name to a space separated list of packages. If the key package is star-imported, assume all packages in the 'value' part of the MapEntry are too. */
+ public static final Map<String, Collection<String>> IMPLIED_EXTRA_STAR_IMPORTS;
public static final Map<String, String> ALIASES;
/**
@@ -41,12 +43,14 @@ public class LombokInternalAliasing {
}
static {
- Map<String, String> m = new HashMap<String, String>();
- m.put("lombok.experimental", "lombok");
- IMPLIED_EXTRA_STAR_IMPORTS = Collections.unmodifiableMap(m);
+ Map<String, Collection<String>> m1 = new HashMap<String, Collection<String>>();
+ m1.put("lombok.experimental", Collections.singleton("lombok"));
+ m1.put("lombok", Collections.singleton("lombok.experimental"));
+ IMPLIED_EXTRA_STAR_IMPORTS = Collections.unmodifiableMap(m1);
- m = new HashMap<String, String>();
- m.put("lombok.experimental.Value", "lombok.Value");
- ALIASES = Collections.unmodifiableMap(m);
+ Map<String, String> m2 = new HashMap<String, String>();
+ m2.put("lombok.experimental.Value", "lombok.Value");
+ m2.put("lombok.Delegate", "lombok.experimental.Delegate");
+ ALIASES = Collections.unmodifiableMap(m2);
}
}
diff --git a/src/core/lombok/eclipse/EclipseImportList.java b/src/core/lombok/eclipse/EclipseImportList.java
index 69246b3c..47167ec6 100644
--- a/src/core/lombok/eclipse/EclipseImportList.java
+++ b/src/core/lombok/eclipse/EclipseImportList.java
@@ -62,15 +62,23 @@ public class EclipseImportList implements ImportList {
}
@Override public boolean hasStarImport(String packageName) {
- for (Map.Entry<String, String> e : LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.entrySet()) {
- if (e.getValue().equals(packageName) && hasStarImport(e.getKey())) return true;
- }
if (isEqual(packageName, pkg)) return true;
if ("java.lang".equals(packageName)) return true;
+
+ if (pkg != null && pkg.tokens != null && pkg.tokens.length == 0) {
+ for (Map.Entry<String, Collection<String>> e : LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.entrySet()) {
+ if (isEqual(e.getKey(), pkg) && e.getValue().contains(packageName)) return true;
+ }
+ }
+
if (imports != null) for (ImportReference imp : imports) {
if ((imp.bits & ASTNode.OnDemand) == 0) continue;
if (imp.isStatic()) continue;
if (isEqual(packageName, imp)) return true;
+ for (Map.Entry<String, Collection<String>> e : LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.entrySet()) {
+ if (isEqual(e.getKey(), imp) && e.getValue().contains(packageName)) return true;
+ }
+
}
return false;
}
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index 8cffaa2c..d3d974c9 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -34,7 +34,7 @@ import java.util.Map;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
-import lombok.Delegate;
+import lombok.experimental.Delegate;
import lombok.Getter;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
diff --git a/src/core/lombok/experimental/Delegate.java b/src/core/lombok/experimental/Delegate.java
new file mode 100644
index 00000000..806d5871
--- /dev/null
+++ b/src/core/lombok/experimental/Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010-2014 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.experimental;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Put on any field to make lombok generate delegate methods that forward the call to this field.
+ *
+ * Example:
+ * <pre>
+ * private &#64;Delegate List&lt;String&gt; foo;
+ * </pre>
+ *
+ * will generate for example an {@code boolean add(String)} method, which contains: {@code return foo.add(arg);}, as well as all other methods in {@code List}.
+ *
+ * All public instance methods of the field's type, as well as all public instance methods of all the field's type's superfields are delegated, except for all methods
+ * that exist in {@link Object}, the {@code canEqual(Object)} method, and any methods that appear in types
+ * that are listed in the {@code excludes} property.
+ * <p>
+ * Complete documentation is found at <a href="http://projectlombok.org/features/experimental/Delegate.html">the project lombok features page for &#64;Delegate</a>.
+ */
+@Target({ElementType.FIELD, ElementType.METHOD})
+@Retention(RetentionPolicy.SOURCE)
+public @interface Delegate {
+ /**
+ * Normally the type of the field is used as delegate type. However, to choose a different type to delegate, you can list one (or more) types here. Note that types with
+ * type arguments can only be done as a field type. A solution for this is to create a private inner interface/class with the appropriate types extended, and possibly
+ * with all methods you'd like to delegate listed, and then supply that class here. The field does not actually have to implement the type you're delegating; the
+ * type listed here is used only to determine which delegate methods to generate.
+ *
+ * NB: All methods in {@code Object}, as well as {@code canEqual(Object other)} will never be delegated.
+ */
+ Class<?>[] types() default {};
+
+ /**
+ * Each method in any of the types listed here (include supertypes) will <em>not</em> be delegated.
+ *
+ * NB: All methods in {@code Object}, as well as {@code canEqual(Object other)} will never be delegated.
+ */
+ Class<?>[] excludes() default {};
+}
diff --git a/src/core/lombok/javac/JavacImportList.java b/src/core/lombok/javac/JavacImportList.java
index d5d7460a..2665ca7c 100644
--- a/src/core/lombok/javac/JavacImportList.java
+++ b/src/core/lombok/javac/JavacImportList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Project Lombok Authors.
+ * Copyright (C) 2013-2014 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,6 @@ package lombok.javac;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Map;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -59,12 +58,15 @@ public class JavacImportList implements ImportList {
}
@Override public boolean hasStarImport(String packageName) {
- for (Map.Entry<String, String> e : LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.entrySet()) {
- if (e.getValue().equals(packageName) && hasStarImport(e.getKey())) return true;
- }
- if (pkg != null && pkg.toString().equals(packageName)) return true;
+ String pkgStr = pkg == null ? null : pkg.toString();
+ if (pkgStr != null && pkgStr.equals(packageName)) return true;
if ("java.lang".equals(packageName)) return true;
+ if (pkgStr != null) {
+ Collection<String> extra = LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.get(pkgStr);
+ if (extra != null && extra.contains(packageName)) return true;
+ }
+
for (JCTree def : defs) {
if (!(def instanceof JCImport)) continue;
if (((JCImport) def).staticImport) continue;
@@ -72,7 +74,10 @@ public class JavacImportList implements ImportList {
if (!(qual instanceof JCFieldAccess)) continue;
String simpleName = ((JCFieldAccess) qual).name.toString();
if (!"*".equals(simpleName)) continue;
- if (packageName.equals(((JCFieldAccess) qual).selected.toString())) return true;
+ String starImport = ((JCFieldAccess) qual).selected.toString();
+ if (packageName.equals(starImport)) return true;
+ Collection<String> extra = LombokInternalAliasing.IMPLIED_EXTRA_STAR_IMPORTS.get(starImport);
+ if (extra != null && extra.contains(packageName)) return true;
}
return false;
diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java
index ec6ea20c..9cd8844e 100644
--- a/src/core/lombok/javac/handlers/HandleDelegate.java
+++ b/src/core/lombok/javac/handlers/HandleDelegate.java
@@ -25,6 +25,7 @@ import static lombok.core.handlers.HandlerUtil.*;
import static lombok.javac.handlers.JavacHandlerUtil.*;
import static com.sun.tools.javac.code.Flags.*;
+import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -42,7 +43,7 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import lombok.ConfigurationKeys;
-import lombok.Delegate;
+import lombok.experimental.Delegate;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
@@ -101,7 +102,8 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> {
@Override public void handle(AnnotationValues<Delegate> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.DELEGATE_FLAG_USAGE, "@Delegate");
- deleteAnnotationIfNeccessary(annotationNode, Delegate.class);
+ @SuppressWarnings("deprecation") Class<? extends Annotation> oldDelegate = lombok.Delegate.class;
+ deleteAnnotationIfNeccessary(annotationNode, Delegate.class, oldDelegate);
Type delegateType;
Name delegateName = annotationNode.toName(annotationNode.up().getName());
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 48a13bde..063741e2 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -33,7 +33,7 @@ import java.util.Map;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
-import lombok.Delegate;
+import lombok.experimental.Delegate;
import lombok.Getter;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
diff --git a/website/features/Log.html b/website/features/Log.html
index bc9e017e..f47835c1 100644
--- a/website/features/Log.html
+++ b/website/features/Log.html
@@ -59,7 +59,7 @@
</div>
</div>
<div class="footer">
- <a href="index.html">Back to features</a> | <a href="GetterLazy.html">Previous feature (@Getter(lazy=true))</a> | <a href="Delegate.html">Next feature (@Delegate)</a><br />
+ <a href="index.html">Back to features</a> | <a href="GetterLazy.html">Previous feature (@Getter(lazy=true))</a> | <span class="disabled">Next feature</span><br />
<a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2013 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
</div>
<div style="clear: both;"></div>
diff --git a/website/features/Delegate.html b/website/features/experimental/Delegate.html
index 02cdf290..6f745f31 100644
--- a/website/features/Delegate.html
+++ b/website/features/experimental/Delegate.html
@@ -1,38 +1,48 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <link rel="stylesheet" type="text/css" href="../logi/reset.css" />
- <link rel="stylesheet" type="text/css" href="features.css" />
- <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
+ <link rel="stylesheet" type="text/css" href="../../logi/reset.css" />
+ <link rel="stylesheet" type="text/css" href="../features.css" />
+ <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon" />
<meta name="description" content="Spice up your java" />
<title>@Delegate</title>
</head><body><div id="pepper">
<div class="minimumHeight"></div>
<div class="meat">
- <div class="header"><a href="../index.html">Project Lombok</a></div>
+ <div class="header"><a href="../../index.html">Project Lombok</a></div>
<h1>@Delegate</h1>
<div class="byline">Don't lose your composition.</div>
- <div class="overview">
- <h3>Overview</h3>
+ <div class="since">
+ <h3>Since</h3>
<p>
- <em> NEW IN Lombok 0.10: </em> Any field or no-argument method can be annotated with <code>@Delegate</code> to let lombok generate delegate methods
- that forward the call to this field (or the result of invoking this method).
+ @Delegate was introduced as feature in lombok v0.10. It was moved to the experimental package in lombok v1.14; the old version from the main lombok package is now deprecated.
</p>
+ </div>
+ <div class="experimental">
+ <h3>Experimental</h3>
<p>
- Lombok delegates all <code>public</code> methods of the field's type (or method's return type), as well as those of its supertype except for all
- methods declared in <code>java.lang.Object</code>.
- </p>
+ Experimental because:
+ <ul>
+ <li>Not used that much</li>
+ <li>Difficult to support for edge cases, such as recursive delegation.</li>
+ <li>API is rather unfriendly; it would be a lot nicer if you can simply implement some methods and let <code>@Delegate</code> generate delegates for whatever you didn't manually implement, but due to issues with generics erasure this also can't be made to work without caveats.
+ </ul>
+ Current status: <em>negative</em> - Currently we feel this feature will not move out of experimental status anytime soon, and support for this feature may be dropped if future versions of javac or ecj make it difficult to continue to maintain the feature.
+ </div>
+ <div class="overview">
+ <h3>Overview</h3>
<p>
+ Any field or no-argument method can be annotated with <code>@Delegate</code> to let lombok generate delegate methods that forward the call to this field (or the result of invoking this method).
+ </p><p>
+ Lombok delegates all <code>public</code> methods of the field's type (or method's return type), as well as those of its supertypes except for all
+ methods declared in <code>java.lang.Object</code>.
+ </p><p>
You can pass any number of classes into the <code>@Delegate</code> annotation's <code>types</code> parameter.
- If you do that, then lombok will delegate all <code>public</code> methods in those types (and their supertypes, except
- <code>java.lang.Object</code>) instead of looking at the field/method's type.
- </p>
- <p>
- All public non-<code>Object</code> methods that are part of the calculated type(s) are
- copied, whether or not you also wrote implementations for those methods. That would thus result in duplicate method errors. You can avoid these
+ If you do that, then lombok will delegate all <code>public</code> methods in those types (and their supertypes, except <code>java.lang.Object</code>) instead of looking at the field/method's type.
+ </p><p>
+ All public non-<code>Object</code> methods that are part of the calculated type(s) are copied, whether or not you also wrote implementations for those methods. That would thus result in duplicate method errors. You can avoid these
by using the <code>@Delegate(excludes=SomeType.class)</code> parameter to exclude all public methods in the excluded type(s), and their supertypes.
- </p>
- <p>
+ </p><p>
To have very precise control over what is delegated and what isn't, write private inner interfaces with method signatures, then specify these
private inner interfaces as types in <code>@Delegate(types=PrivateInnerInterfaceWithIncludesList.class, excludes=SameForExcludes.class)</code>.
</p>
@@ -59,12 +69,13 @@
When passing classes to the annotation, these classes do not need to be supertypes of the field. See the example.
</p><p>
<code>@Delegate</code> cannot be used on static fields or methods.
- </p>
+ </p><p>
+ <code>@Delegate</code> cannot be used when the calculated type(s) to delegate / exclude themselves contain <code>@Delegate</code> annotations; in other words, <code>@Delegate</code> will error if you attempt to use it recursively.
</div>
</div>
<div class="footer">
- <a href="index.html">Back to features</a> | <a href="Log.html">Previous feature (@Log)</a> | <span class="disabled">Next feature</span><br />
- <a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2010-2013 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
+ <a href="index.html">Back to features</a> | <a href="FieldDefaults.html">Previous feature (@FieldDefaults)</a> | <a href="Wither.html">Next feature (@Wither)</a><br />
+ <a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2010-2013 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
</div>
<div style="clear: both;"></div>
</div>
diff --git a/website/features/experimental/FieldDefaults.html b/website/features/experimental/FieldDefaults.html
index eff709ca..969da230 100644
--- a/website/features/experimental/FieldDefaults.html
+++ b/website/features/experimental/FieldDefaults.html
@@ -65,7 +65,7 @@
</div>
</div>
<div class="footer">
- <a href="index.html">Back to experimental features</a> | <a href="ExtensionMethod.html">Previous feature (@ExtensionMethod)</a> | <a href="Wither.html">Next feature (@Wither)</a><br />
+ <a href="index.html">Back to experimental features</a> | <a href="ExtensionMethod.html">Previous feature (@ExtensionMethod)</a> | <a href="Delegate.html">Next feature (@Delegate)</a><br />
<a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2013 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
</div>
<div style="clear: both;"></div>
diff --git a/website/features/experimental/Wither.html b/website/features/experimental/Wither.html
index 46d3b08b..b6634be4 100644
--- a/website/features/experimental/Wither.html
+++ b/website/features/experimental/Wither.html
@@ -85,7 +85,7 @@
</div>
</div>
<div class="footer">
- <a href="index.html">Back to experimental features</a> | <a href="FieldDefaults.html">Previous feature (@FieldDefaults)</a> | <a href="onX.html">Next feature (onX)</a><br />
+ <a href="index.html">Back to experimental features</a> | <a href="Delegate.html">Previous feature (@Delegate)</a> | <a href="onX.html">Next feature (onX)</a><br />
<a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2013 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
</div>
<div style="clear: both;"></div>
diff --git a/website/features/experimental/index.html b/website/features/experimental/index.html
index 1128787c..9a1c505f 100644
--- a/website/features/experimental/index.html
+++ b/website/features/experimental/index.html
@@ -30,6 +30,8 @@
<dd>Annoying API? Fix it yourself: Add new methods to existing types!</dd>
<dt><a href="FieldDefaults.html"><code>@FieldDefaults</code></a></dt>
<dd>New default field modifiers for the 21st century.</dd>
+ <dt><a href="Delegate.html"><code>@Delegate</code></a></dt>
+ <dd>Don't lose your composition.</dd>
<dt><a href="Wither.html"><code>@Wither</code></a></dt>
<dd>Immutable 'setters' - methods that create a clone but with one changed field.</dd>
<dt><a href="onX.html"><code>onMethod= / onConstructor= / onParam=</code></a></dt>
diff --git a/website/features/index.html b/website/features/index.html
index f9b8cdfa..537ed166 100644
--- a/website/features/index.html
+++ b/website/features/index.html
@@ -40,8 +40,6 @@
<dd>Laziness is a virtue!</dd>
<dt><a href="Log.html"><code>@Log</code></a></dt>
<dd>Captain's Log, stardate 24435.7: &quot;What was that line again?&quot;</dd>
- <dt><a href="Delegate.html"><code>@Delegate</code></a></dt>
- <dd>Don't lose your composition.</dd>
<dt><a href="experimental/index.html">experimental features</a></dt>
<dd>Here be dragons: Extra features which aren't quite ready for prime time yet.</dd>
</dl>