/**
* Copyright (c) 2012-2016 André Bargull
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms.
*
* <https://github.com/anba/es6draft>
*/
package com.github.anba.es6draft.runtime.objects.promise;
import java.util.ArrayList;
import java.util.List;
import com.github.anba.es6draft.runtime.Realm;
import com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject;
/**
* <h1>25 Control Abstraction Objects</h1><br>
* <h2>25.4 Promise Objects</h2>
* <ul>
* <li>25.4.6 Properties of Promise Instances
* </ul>
*/
public class PromiseObject extends OrdinaryObject {
public enum State {
Pending, Fulfilled, Rejected
}
/** [[PromiseState]] */
private State state;
/** [[PromiseResult]] */
private Object result;
/** [[PromiseFulfillReactions]] */
private ArrayList<PromiseReaction> fulfillReactions;
/** [[PromiseRejectReactions]] */
private ArrayList<PromiseReaction> rejectReactions;
/**
* Constructs a new Promise object.
*
* @param realm
* the realm object
*/
public PromiseObject(Realm realm) {
super(realm);
state = PromiseObject.State.Pending;
fulfillReactions = new ArrayList<>();
rejectReactions = new ArrayList<>();
}
@Override
public String toString() {
return String.format("%s, state=%s", super.toString(), state);
}
/*package*/void notifyRejectReaction(PromiseReaction reaction) {
// override in sub-class
}
/*package*/void notifyReject(Object reason) {
// override in sub-class
}
/**
* [[PromiseState]]
*
* @return the promise state
*/
public final State getState() {
return state;
}
/**
* [[PromiseResult]]
*
* @return the promise result value
*/
public final Object getResult() {
assert state == State.Fulfilled || state == State.Rejected;
return result;
}
/**
* [[PromiseFulfillReactions]]
*
* @param reaction
* the fulfill reaction
*/
public final void addFulfillReaction(PromiseReaction reaction) {
assert state == State.Pending;
fulfillReactions.add(reaction);
}
/**
* [[PromiseRejectReactions]]
*
* @param reaction
* the reject reaction
*/
public final void addRejectReaction(PromiseReaction reaction) {
assert state == State.Pending;
rejectReactions.add(reaction);
}
/**
* Fulfills the pending promise with <var>value</var>.
*
* @param value
* the fulfillment value
* @return the list of collected promise reaction records
*/
public final List<PromiseReaction> fufill(Object value) {
List<PromiseReaction> reactions = fulfillReactions;
resolve(State.Fulfilled, value);
return reactions;
}
/**
* Rejects the pending promise with <var>reason</var>.
*
* @param reason
* the rejection value
* @return the list of collected promise reaction records
*/
public final List<PromiseReaction> reject(Object reason) {
List<PromiseReaction> reactions = rejectReactions;
resolve(State.Rejected, reason);
notifyReject(reason);
return reactions;
}
private void resolve(State state, Object result) {
assert this.state == State.Pending;
this.result = result;
this.fulfillReactions = null;
this.rejectReactions = null;
this.state = state;
}
}