package org.realityforge.arez.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;

/**
 * Annotation that marks classes to be processed by Arez annotation processor.
 * Classes with this annotation can contain {@link Observable} properties,
 * {@link Computed} properties and {@link Action} methods.
 *
 * <p>The annotation controls the way that contained actions and observables are
 * named (if names are enabled in the system.</p>
 * <ul>
 * <li>The value returned by {@link #name()} indicates the type name for instances
 * of this object. If not specified it will default to the SimpleName of the class.
 * i.e. The class <tt>com.biz.models.MyModel</tt> will default to a name of
 * "MyModel".</li>
 * <li>The {@link #singleton()} method indicates whether there are expected to be
 * multiple instances of this type or just one. If the method returns true then the
 * debug name of contained observables will not include the "id" of the instance.</li>
 * </ul>
 * <p>The name of any elements contained within the component follows the pattern
 * "<tt>[ArezComponent.name].[ArezComponent.id].[Element.name]</tt>". If the value of {@link #name()}
 * is the empty string then the "<tt>[ArezComponent.name].</tt>" element of name will be elided.
 * If the value of {@link #singleton()} is true then the "<tt>[ArezComponent.id].</tt>" element
 * of the name will be elided.</p>
 *
 * <p>The type that is annotated with @ArezComponent must comply with the additional constraints:</p>
 * <ul>
 * <li>Must be a class, not an interface or enum</li>
 * <li>Must be concrete, not abstract</li>
 * <li>Must not be final</li>
 * <li>Must not be a non-static nested class</li>
 * <li>Must have at least one method annotated with {@link Action}, {@link Computed} or {@link Observable}</li>
 * </ul>
 *
 * <p>The annotation processor that handles this annotation will analyze all super classes and super
 * interfaces. This includes analysis of default methods on interfaces. So it is perfectly valid to
 * add {@link Observable}, {@link Computed}, {@link Action}, {@link PreDispose} and {@link PostDispose}
 * annotations to default methods on implemented interfaces.</p>
 */
@Documented
@Target( ElementType.TYPE )
public @interface ArezComponent
{
  /**
   * Return the name of the type.
   * The value must conform to the requirements of a java identifier.
   * This can be set to the empty string in which case the {@link Observable}, {@link Computed} and
   * {@link Action} sub-elements will have no type prefix.
   *
   * @return the name of the type.
   */
  @Nonnull
  String name() default "<default>";

  /**
   * Return true if the component can only have a single instance, false otherwise.
   *
   * @return true if the component can only have a single instance, false otherwise.
   */
  boolean singleton() default false;

  /**
   * Return true if the generated component should implement the Disposable interface.
   *
   * @return true if the generated component should implement the Disposable interface, false otherwise.
   */
  boolean disposable() default true;

  /**
   * Return true if the component does not need to explicitly declare elements.
   * Otherwise if no elements (i.e. {@link Observable}s, {@link Action}s, {@link Autorun}s etc) are defined
   * on a component it will generate an error.
   *
   * @return true if the component does not need to explicitly declare elements, false otherwise.
   */
  boolean allowEmpty() default false;
}

@@ -376,16 +376,67 @@
 operties
+, %7B@link Autorun%7D methods, %7B@link Track%7D methods%0A *
  and %7B@l
@@ -1883,32 +1883,64 @@
  %7B@link Action%7D,
+ %7B@link Autorun%7D, %7B@link Track%7D,
  %7B@link Computed

Update javadocs