Abnaxos / markdown-doclet

A Doclet that allows the use of Markdown in JavaDoc comments.
GNU General Public License v3.0
319 stars 40 forks source link

Example text that which hangs #57

Open nedtwigg opened 8 years ago

nedtwigg commented 8 years ago

This is an extreme case, so closing this without further investigation is totally valid :)

The following text [A], when placed in a package-info.java file, will cause pegdown doclet to fail with:

package-info.java:151: error - Error while parsing action 'Root/Sequence/ZeroOrMore/Sequence/Block/FirstOf/Table/Sequence/Optional/Sequence/NodeSequence/Sequence/TableRow/Sequence/OneOrMore/Sequence/TableCell/NodeSequence/Sequence/OneOrMore/Sequence/Inline/Inline_Action1' at input position (line 27, pos 1):
<p>To register your listener methods with the event producers...

But the twice as large text [B] (which has the same beginning, but is a little longer) will cause the pegdown doclet to hang forever (or at least 10 minutes).

I was able to get it to pass by converting to [C]. All of this is with 1.3.0.

[A]

/**
 * The EventBus allows publish-subscribe-style communication between components
 * without requiring the components to explicitly register with one another
 * (and thus be aware of each other).  It is designed exclusively to replace
 * traditional Java in-process event distribution using explicit registration.
 * It is <em>not</em> a general-purpose publish-subscribe system, nor is it
 * intended for interprocess communication.
 * 
 * <p>See the Guava User Guide article on <a href=
 * "https://github.com/google/guava/wiki/EventBusExplained">
 * {@code EventBus}</a>.
 *
 * <h2>One-Minute Guide</h2>
 *
 * <p>Converting an existing EventListener-based system to use the EventBus is
 * easy.
 *
 * <h3>For Listeners</h3>
 * <p>To listen for a specific flavor of event (say, a CustomerChangeEvent)...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> implement an interface
 *     defined with the event &mdash; such as CustomerChangeEventListener.</li>
 * <li><strong>...with EventBus:</strong> create a method that accepts
 *     CustomerChangeEvent as its sole argument, and mark it with the
 *     {@link com.diffplug.common.eventbus.Subscribe} annotation.</li>
 * </ul>
 *
 * <p>To register your listener methods with the event producers...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> pass your object to each
 *     producer's {@code registerCustomerChangeEventListener} method.  These
 *     methods are rarely defined in common interfaces, so in addition to
 *     knowing every possible producer, you must also know its type.</li>
 * <li><strong>...with EventBus:</strong> pass your object to the
 *     {@link com.diffplug.common.eventbus.EventBus#register(Object)} method on an
 *     EventBus.  You'll need to
 *     make sure that your object shares an EventBus instance with the event
 *     producers.</li>
 * </ul>
 *
 * <p>To listen for a common event supertype (such as EventObject or Object)...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> not easy.</li>
 * <li><strong>...with EventBus:</strong> events are automatically dispatched to
 *     listeners of any supertype, allowing listeners for interface types
 *     or "wildcard listeners" for Object.</li>
 * </ul>
 *
 * <p>To listen for and detect events that were dispatched without listeners...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> add code to each
 *     event-dispatching method (perhaps using AOP).</li>
 * <li><strong>...with EventBus:</strong> subscribe to {@link
 *     com.diffplug.common.eventbus.DeadEvent}.  The
 *     EventBus will notify you of any events that were posted but not
 *     delivered.  (Handy for debugging.)</li>
 * </ul>
 *
 * <h3>For Producers</h3>
 * <p>To keep track of listeners to your events...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> write code to manage
 *     a list of listeners to your object, including synchronization, or use a
 *     utility class like EventListenerList.</li>
 * <li><strong>...with EventBus:</strong> EventBus does this for you.</li>
 * </ul>
 *
 * <p>To dispatch an event to listeners...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> write a method to
 *     dispatch events to each event listener, including error isolation and
 *     (if desired) asynchronicity.</li>
 * <li><strong>...with EventBus:</strong> pass the event object to an EventBus's
 *     {@link com.diffplug.common.eventbus.EventBus#post(Object)} method.</li>
 * </ul>
 *
 * <h2>Glossary</h2>
 *
 * <p>The EventBus system and code use the following terms to discuss event
 * distribution:
 * <dl>
 * <dt>Event</dt><dd>Any object that may be <em>posted</em> to a bus.</dd>
 * <dt>Subscribing</dt><dd>The act of registering a <em>listener</em> with an
 *     EventBus, so that its <em>subscriber methods</em> will receive events.</dd>
 * <dt>Listener</dt><dd>An object that wishes to receive events, by exposing
 *     <em>subscriber methods</em>.</dt>
 * <dt>Subscriber method</dt><dd>A public method that the EventBus should use to
 *     deliver <em>posted</em> events.  Subscriber methods are marked by the
 *     {@link com.diffplug.common.eventbus.Subscribe} annotation.</dd>
 * <dt>Posting an event</dt><dd>Making the event available to any
 *     <em>listeners</em> through the EventBus.</dt>
 * </dl>
 *
 * <h2>FAQ</h2>
 * <h3>Why must I create my own Event Bus, rather than using a singleton?</h3>
 *
 * <p>The Event Bus doesn't specify how you use it; there's nothing stopping your
 * application from having separate EventBus instances for each component, or
 * using separate instances to separate events by context or topic.  This also
 * makes it trivial to set up and tear down EventBus objects in your tests.
 *
 * <p>Of course, if you'd like to have a process-wide EventBus singleton,
 * there's nothing stopping you from doing it that way.  Simply have your
 * container (such as Guice) create the EventBus as a singleton at global scope
 * (or stash it in a static field, if you're into that sort of thing).
 *
 * <p>In short, the EventBus is not a singleton because we'd rather not make
 * that decision for you.  Use it how you like.
 *
 * <h3>Why use an annotation to mark subscriber methods, rather than requiring the
 * listener to implement an interface?</h3>
 * <p>We feel that the Event Bus's {@code @Subscribe} annotation conveys your
 * intentions just as explicitly as implementing an interface (or perhaps more
 * so), while leaving you free to place event subscriber methods wherever you wish
 * and give them intention-revealing names.
 *
 * <p>Traditional Java Events use a listener interface which typically sports
 * only a handful of methods -- typically one.  This has a number of
 * disadvantages:
 * <ul>
 *   <li>Any one class can only implement a single response to a given event.
 *   <li>Listener interface methods may conflict.
 *   <li>The method must be named after the event (e.g. {@code
 *       handleChangeEvent}), rather than its purpose (e.g. {@code
 *       recordChangeInJournal}).
 *   <li>Each event usually has its own interface, without a common parent
 *       interface for a family of events (e.g. all UI events).
 * </ul>
 *
 * <p>The difficulties in implementing this cleanly has given rise to a pattern,
 * particularly common in Swing apps, of using tiny anonymous classes to
 * implement event listener interfaces.
 * 
 */

[B]

/**
 * The EventBus allows publish-subscribe-style communication between components
 * without requiring the components to explicitly register with one another
 * (and thus be aware of each other).  It is designed exclusively to replace
 * traditional Java in-process event distribution using explicit registration.
 * It is <em>not</em> a general-purpose publish-subscribe system, nor is it
 * intended for interprocess communication.
 * 
 * <p>See the Guava User Guide article on <a href=
 * "https://github.com/google/guava/wiki/EventBusExplained">
 * {@code EventBus}</a>.
 *
 * <h2>One-Minute Guide</h2>
 *
 * <p>Converting an existing EventListener-based system to use the EventBus is
 * easy.
 *
 * <h3>For Listeners</h3>
 * <p>To listen for a specific flavor of event (say, a CustomerChangeEvent)...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> implement an interface
 *     defined with the event &mdash; such as CustomerChangeEventListener.</li>
 * <li><strong>...with EventBus:</strong> create a method that accepts
 *     CustomerChangeEvent as its sole argument, and mark it with the
 *     {@link com.diffplug.common.eventbus.Subscribe} annotation.</li>
 * </ul>
 *
 * <p>To register your listener methods with the event producers...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> pass your object to each
 *     producer's {@code registerCustomerChangeEventListener} method.  These
 *     methods are rarely defined in common interfaces, so in addition to
 *     knowing every possible producer, you must also know its type.</li>
 * <li><strong>...with EventBus:</strong> pass your object to the
 *     {@link com.diffplug.common.eventbus.EventBus#register(Object)} method on an
 *     EventBus.  You'll need to
 *     make sure that your object shares an EventBus instance with the event
 *     producers.</li>
 * </ul>
 *
 * <p>To listen for a common event supertype (such as EventObject or Object)...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> not easy.</li>
 * <li><strong>...with EventBus:</strong> events are automatically dispatched to
 *     listeners of any supertype, allowing listeners for interface types
 *     or "wildcard listeners" for Object.</li>
 * </ul>
 *
 * <p>To listen for and detect events that were dispatched without listeners...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> add code to each
 *     event-dispatching method (perhaps using AOP).</li>
 * <li><strong>...with EventBus:</strong> subscribe to {@link
 *     com.diffplug.common.eventbus.DeadEvent}.  The
 *     EventBus will notify you of any events that were posted but not
 *     delivered.  (Handy for debugging.)</li>
 * </ul>
 *
 * <h3>For Producers</h3>
 * <p>To keep track of listeners to your events...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> write code to manage
 *     a list of listeners to your object, including synchronization, or use a
 *     utility class like EventListenerList.</li>
 * <li><strong>...with EventBus:</strong> EventBus does this for you.</li>
 * </ul>
 *
 * <p>To dispatch an event to listeners...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> write a method to
 *     dispatch events to each event listener, including error isolation and
 *     (if desired) asynchronicity.</li>
 * <li><strong>...with EventBus:</strong> pass the event object to an EventBus's
 *     {@link com.diffplug.common.eventbus.EventBus#post(Object)} method.</li>
 * </ul>
 *
 * <h2>Glossary</h2>
 *
 * <p>The EventBus system and code use the following terms to discuss event
 * distribution:
 * <dl>
 * <dt>Event</dt><dd>Any object that may be <em>posted</em> to a bus.</dd>
 * <dt>Subscribing</dt><dd>The act of registering a <em>listener</em> with an
 *     EventBus, so that its <em>subscriber methods</em> will receive events.</dd>
 * <dt>Listener</dt><dd>An object that wishes to receive events, by exposing
 *     <em>subscriber methods</em>.</dt>
 * <dt>Subscriber method</dt><dd>A public method that the EventBus should use to
 *     deliver <em>posted</em> events.  Subscriber methods are marked by the
 *     {@link com.diffplug.common.eventbus.Subscribe} annotation.</dd>
 * <dt>Posting an event</dt><dd>Making the event available to any
 *     <em>listeners</em> through the EventBus.</dt>
 * </dl>
 *
 * <h2>FAQ</h2>
 * <h3>Why must I create my own Event Bus, rather than using a singleton?</h3>
 *
 * <p>The Event Bus doesn't specify how you use it; there's nothing stopping your
 * application from having separate EventBus instances for each component, or
 * using separate instances to separate events by context or topic.  This also
 * makes it trivial to set up and tear down EventBus objects in your tests.
 *
 * <p>Of course, if you'd like to have a process-wide EventBus singleton,
 * there's nothing stopping you from doing it that way.  Simply have your
 * container (such as Guice) create the EventBus as a singleton at global scope
 * (or stash it in a static field, if you're into that sort of thing).
 *
 * <p>In short, the EventBus is not a singleton because we'd rather not make
 * that decision for you.  Use it how you like.
 *
 * <h3>Why use an annotation to mark subscriber methods, rather than requiring the
 * listener to implement an interface?</h3>
 * <p>We feel that the Event Bus's {@code @Subscribe} annotation conveys your
 * intentions just as explicitly as implementing an interface (or perhaps more
 * so), while leaving you free to place event subscriber methods wherever you wish
 * and give them intention-revealing names.
 *
 * <p>Traditional Java Events use a listener interface which typically sports
 * only a handful of methods -- typically one.  This has a number of
 * disadvantages:
 * <ul>
 *   <li>Any one class can only implement a single response to a given event.
 *   <li>Listener interface methods may conflict.
 *   <li>The method must be named after the event (e.g. {@code
 *       handleChangeEvent}), rather than its purpose (e.g. {@code
 *       recordChangeInJournal}).
 *   <li>Each event usually has its own interface, without a common parent
 *       interface for a family of events (e.g. all UI events).
 * </ul>
 *
 * <p>The difficulties in implementing this cleanly has given rise to a pattern,
 * particularly common in Swing apps, of using tiny anonymous classes to
 * implement event listener interfaces.
 *
 * <p>Compare these two cases: <pre>
 *   class ChangeRecorder {
 *     void setCustomer(Customer cust) {
 *       cust.addChangeListener(new ChangeListener() {
 *         void customerChanged(ChangeEvent e) {
 *           recordChange(e.getChange());
 *         }
 *       };
 *     }
 *   }
 *
 *   // Class is typically registered by the container.
 *   class EventBusChangeRecorder {
 *     &#064;Subscribe void recordCustomerChange(ChangeEvent e) {
 *       recordChange(e.getChange());
 *     }
 *   }</pre>
 *
 * <p>The intent is actually clearer in the second case: there's less noise code,
 * and the event subscriber has a clear and meaningful name.
 *
 * <h3>What about a generic {@code Subscriber<T>} interface?</h3>
 * <p>Some have proposed a generic {@code Subscriber<T>} interface for EventBus
 * listeners.  This runs into issues with Java's use of type erasure, not to
 * mention problems in usability.
 *
 * <p>Let's say the interface looked something like the following: <pre>   {@code
 *   interface Subscriber<T> {
 *     void handleEvent(T event);
 *   }}</pre>
 *
 * <p>Due to erasure, no single class can implement a generic interface more than
 * once with different type parameters.  This is a giant step backwards from
 * traditional Java Events, where even if {@code actionPerformed} and {@code
 * keyPressed} aren't very meaningful names, at least you can implement both
 * methods!
 *
 * <h3>Doesn't EventBus destroy static typing and eliminate automated
 * refactoring support?</h3>
 * <p>Some have freaked out about EventBus's {@code register(Object)} and {@code
 * post(Object)} methods' use of the {@code Object} type.
 *
 * <p>{@code Object} is used here for a good reason: the Event Bus library
 * places no restrictions on the types of either your event listeners (as in
 * {@code register(Object)}) or the events themselves (in {@code post(Object)}).
 *
 * <p>Event subscriber methods, on the other hand, must explicitly declare their
 * argument type -- the type of event desired (or one of its supertypes).  Thus,
 * searching for references to an event class will instantly find all subscriber
 * methods for that event, and renaming the type will affect all subscriber methods
 * within view of your IDE (and any code that creates the event).
 *
 * <p>It's true that you can rename your {@code @Subscribed} event subscriber
 * methods at will; Event Bus will not stop this or do anything to propagate the
 * rename because, to Event Bus, the names of your subscriber methods are
 * irrelevant.  Test code that calls the methods directly, of course, will be
 * affected by your renaming -- but that's what your refactoring tools are for.
 *
 * <h3>What happens if I {@code register} a listener without any subscriber
 * methods?</h3>
 * <p>Nothing at all.
 *
 * <p>The Event Bus was designed to integrate with containers and module
 * systems, with Guice as the prototypical example.  In these cases, it's
 * convenient to have the container/factory/environment pass <i>every</i>
 * created object to an EventBus's {@code register(Object)} method.
 *
 * <p>This way, any object created by the container/factory/environment can
 * hook into the system's event model simply by exposing subscriber methods.
 *
 * <h3>What Event Bus problems can be detected at compile time?</h3>
 * <p>Any problem that can be unambiguously detected by Java's type system.  For
 * example, defining a subscriber method for a nonexistent event type.
 *
 * <h3>What Event Bus problems can be detected immediately at registration?</h3>
 * <p>Immediately upon invoking {@code register(Object)}, the listener being
 * registered is checked for the <i>well-formedness</i> of its subscriber methods.
 * Specifically, any methods marked with {@code @Subscribe} must take only a
 * single argument.
 *
 * <p>Any violations of this rule will cause an {@code IllegalArgumentException}
 * to be thrown.
 *
 * <p>(This check could be moved to compile-time using APT, a solution we're
 * researching.)
 *
 * <h3>What Event Bus problems may only be detected later, at runtime?</h3>
 * <p>If a component posts events with no registered listeners, it <i>may</i>
 * indicate an error (typically an indication that you missed a
 * {@code @Subscribe} annotation, or that the listening component is not loaded).
 *
 * <p>(Note that this is <i>not necessarily</i> indicative of a problem.  There
 * are many cases where an application will deliberately ignore a posted event,
 * particularly if the event is coming from code you don't control.)
 *
 * <p>To handle such events, register a subscriber method for the {@code DeadEvent}
 * class.  Whenever EventBus receives an event with no registered subscribers, it
 * will turn it into a {@code DeadEvent} and pass it your way -- allowing you to
 * log it or otherwise recover.
 *
 * <h3>How do I test event listeners and their subscriber methods?</h3>
 * <p>Because subscriber methods on your listener classes are normal methods, you can
 * simply call them from your test code to simulate the EventBus.
 */

[C]

/**
 * The EventBus allows publish-subscribe-style communication between components
 * without requiring the components to explicitly register with one another
 * (and thus be aware of each other).  It is designed exclusively to replace
 * traditional Java in-process event distribution using explicit registration.
 * It is <em>not</em> a general-purpose publish-subscribe system, nor is it
 * intended for interprocess communication.
 * 
 * See the Guava User Guide article on <a href=
 * "https://github.com/google/guava/wiki/EventBusExplained">
 * {@code EventBus}</a>.
 *
 * <h2>One-Minute Guide</h2>
 *
 * Converting an existing EventListener-based system to use the EventBus is
 * easy.
 *
 * <h3>For Listeners</h3>
 * To listen for a specific flavor of event (say, a CustomerChangeEvent)...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> implement an interface
 *     defined with the event &mdash; such as CustomerChangeEventListener.</li>
 * <li><strong>...with EventBus:</strong> create a method that accepts
 *     CustomerChangeEvent as its sole argument, and mark it with the
 *     {@link com.diffplug.common.eventbus.Subscribe} annotation.</li>
 * </ul>
 *
 * To register your listener methods with the event producers...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> pass your object to each
 *     producer's {@code registerCustomerChangeEventListener} method.  These
 *     methods are rarely defined in common interfaces, so in addition to
 *     knowing every possible producer, you must also know its type.</li>
 * <li><strong>...with EventBus:</strong> pass your object to the
 *     {@link com.diffplug.common.eventbus.EventBus#register(Object)} method on an
 *     EventBus.  You'll need to
 *     make sure that your object shares an EventBus instance with the event
 *     producers.</li>
 * </ul>
 *
 * To listen for a common event supertype (such as EventObject or Object)...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> not easy.</li>
 * <li><strong>...with EventBus:</strong> events are automatically dispatched to
 *     listeners of any supertype, allowing listeners for interface types
 *     or "wildcard listeners" for Object.</li>
 * </ul>
 *
 * To listen for and detect events that were dispatched without listeners...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> add code to each
 *     event-dispatching method (perhaps using AOP).</li>
 * <li><strong>...with EventBus:</strong> subscribe to {@link
 *     com.diffplug.common.eventbus.DeadEvent}.  The
 *     EventBus will notify you of any events that were posted but not
 *     delivered.  (Handy for debugging.)</li>
 * </ul>
 *
 * <h3>For Producers</h3>
 * To keep track of listeners to your events...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> write code to manage
 *     a list of listeners to your object, including synchronization, or use a
 *     utility class like EventListenerList.</li>
 * <li><strong>...with EventBus:</strong> EventBus does this for you.</li>
 * </ul>
 *
 * To dispatch an event to listeners...
 * <ul>
 * <li><strong>...in traditional Java events:</strong> write a method to
 *     dispatch events to each event listener, including error isolation and
 *     (if desired) asynchronicity.</li>
 * <li><strong>...with EventBus:</strong> pass the event object to an EventBus's
 *     {@link com.diffplug.common.eventbus.EventBus#post(Object)} method.</li>
 * </ul>
 *
 * <h2>Glossary</h2>
 *
 * The EventBus system and code use the following terms to discuss event
 * distribution:
 *
 * - **Event**: Any object that may be <em>posted</em> to a bus.
 * - **Subscribing**: The act of registering a <em>listener</em> with an
 *     EventBus, so that its <em>subscriber methods</em> will receive events.
 * - **Listener**: An object that wishes to receive events, by exposing
 *     <em>subscriber methods</em>.
 * - **Subscriber method**: A public method that the EventBus should use to
 *     deliver <em>posted</em> events.  Subscriber methods are marked by the
 *     {@link com.diffplug.common.eventbus.Subscribe} annotation.
 * **Posting an event**: Making the event available to any
 *     <em>listeners</em> through the EventBus.
 *
 * <h2>FAQ</h2>
 * <h3>Why must I create my own Event Bus, rather than using a singleton?</h3>
 *
 * The Event Bus doesn't specify how you use it; there's nothing stopping your
 * application from having separate EventBus instances for each component, or
 * using separate instances to separate events by context or topic.  This also
 * makes it trivial to set up and tear down EventBus objects in your tests.
 *
 * Of course, if you'd like to have a process-wide EventBus singleton,
 * there's nothing stopping you from doing it that way.  Simply have your
 * container (such as Guice) create the EventBus as a singleton at global scope
 * (or stash it in a static field, if you're into that sort of thing).
 *
 * In short, the EventBus is not a singleton because we'd rather not make
 * that decision for you.  Use it how you like.
 *
 * <h3>Why use an annotation to mark subscriber methods, rather than requiring the
 * listener to implement an interface?</h3>
 * We feel that the Event Bus's {@code @Subscribe} annotation conveys your
 * intentions just as explicitly as implementing an interface (or perhaps more
 * so), while leaving you free to place event subscriber methods wherever you wish
 * and give them intention-revealing names.
 *
 * Traditional Java Events use a listener interface which typically sports
 * only a handful of methods -- typically one.  This has a number of
 * disadvantages:
 * <ul>
 *   <li>Any one class can only implement a single response to a given event.
 *   <li>Listener interface methods may conflict.
 *   <li>The method must be named after the event (e.g. {@code
 *       handleChangeEvent}), rather than its purpose (e.g. {@code
 *       recordChangeInJournal}).
 *   <li>Each event usually has its own interface, without a common parent
 *       interface for a family of events (e.g. all UI events).
 * </ul>
 *
 * The difficulties in implementing this cleanly has given rise to a pattern,
 * particularly common in Swing apps, of using tiny anonymous classes to
 * implement event listener interfaces.
 *
 * Compare these two cases:
 * <pre>{@code class ChangeRecorder {
 *   void setCustomer(Customer cust) {
 *     cust.addChangeListener(new ChangeListener() {
 *       void customerChanged(ChangeEvent e) {
 *         recordChange(e.getChange());
 *       }
 *     };
 *   }
 * }
 *
 * // Class is typically registered by the container.
 * class EventBusChangeRecorder {
 *   &#064;Subscribe void recordCustomerChange(ChangeEvent e) {
 *     recordChange(e.getChange());
 *   }
 * }
 * }</pre>
 *
 * The intent is actually clearer in the second case: there's less noise code,
 * and the event subscriber has a clear and meaningful name.
 *
 * <h3>What about a generic {@code Subscriber<T>} interface?</h3>
 * Some have proposed a generic {@code Subscriber<T>} interface for EventBus
 * listeners.  This runs into issues with Java's use of type erasure, not to
 * mention problems in usability.
 *
 * Let's say the interface looked something like the following:
 * <pre>{@code interface Subscriber<T> {
 *    void handleEvent(T event);
 *  }}</pre>
 *
 * Due to erasure, no single class can implement a generic interface more than
 * once with different type parameters.  This is a giant step backwards from
 * traditional Java Events, where even if {@code actionPerformed} and {@code
 * keyPressed} aren't very meaningful names, at least you can implement both
 * methods!
 *
 * <h3>Doesn't EventBus destroy static typing and eliminate automated
 * refactoring support?</h3>
 * Some have freaked out about EventBus's {@code register(Object)} and {@code
 * post(Object)} methods' use of the {@code Object} type.
 *
 * {@code Object} is used here for a good reason: the Event Bus library
 * places no restrictions on the types of either your event listeners (as in
 * {@code register(Object)}) or the events themselves (in {@code post(Object)}).
 *
 * Event subscriber methods, on the other hand, must explicitly declare their
 * argument type -- the type of event desired (or one of its supertypes).  Thus,
 * searching for references to an event class will instantly find all subscriber
 * methods for that event, and renaming the type will affect all subscriber methods
 * within view of your IDE (and any code that creates the event).
 *
 * It's true that you can rename your {@code @Subscribed} event subscriber
 * methods at will; Event Bus will not stop this or do anything to propagate the
 * rename because, to Event Bus, the names of your subscriber methods are
 * irrelevant.  Test code that calls the methods directly, of course, will be
 * affected by your renaming -- but that's what your refactoring tools are for.
 *
 * <h3>What happens if I {@code register} a listener without any subscriber
 * methods?</h3>
 * Nothing at all.
 *
 * The Event Bus was designed to integrate with containers and module
 * systems, with Guice as the prototypical example.  In these cases, it's
 * convenient to have the container/factory/environment pass <i>every</i>
 * created object to an EventBus's {@code register(Object)} method.
 *
 * This way, any object created by the container/factory/environment can
 * hook into the system's event model simply by exposing subscriber methods.
 *
 * <h3>What Event Bus problems can be detected at compile time?</h3>
 * Any problem that can be unambiguously detected by Java's type system.  For
 * example, defining a subscriber method for a nonexistent event type.
 *
 * <h3>What Event Bus problems can be detected immediately at registration?</h3>
 * Immediately upon invoking {@code register(Object)}, the listener being
 * registered is checked for the <i>well-formedness</i> of its subscriber methods.
 * Specifically, any methods marked with {@code @Subscribe} must take only a
 * single argument.
 *
 * Any violations of this rule will cause an {@code IllegalArgumentException}
 * to be thrown.
 *
 * (This check could be moved to compile-time using APT, a solution we're
 * researching.)
 *
 * <h3>What Event Bus problems may only be detected later, at runtime?</h3>
 * If a component posts events with no registered listeners, it <i>may</i>
 * indicate an error (typically an indication that you missed a
 * {@code @Subscribe} annotation, or that the listening component is not loaded).
 *
 * (Note that this is <i>not necessarily</i> indicative of a problem.  There
 * are many cases where an application will deliberately ignore a posted event,
 * particularly if the event is coming from code you don't control.)
 *
 * To handle such events, register a subscriber method for the {@code DeadEvent}
 * class.  Whenever EventBus receives an event with no registered subscribers, it
 * will turn it into a {@code DeadEvent} and pass it your way -- allowing you to
 * log it or otherwise recover.
 *
 * <h3>How do I test event listeners and their subscriber methods?</h3>
 * Because subscriber methods on your listener classes are normal methods, you can
 * simply call them from your test code to simulate the EventBus.
 */
Abnaxos commented 8 years ago

That's probably an issue with Pegdown.

  1. It's known that Pegdown may hang in certain situations. That's what the parse timeout is for.
  2. Why didn't it timeout?

I'll have a look at it.