[e-cvs] cvs commit: e/src/jsrc/org/erights/e/ui/jed EAction.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Fri, 7 Sep 2001 14:11:42 -0400
markm 01/09/07 14:11:42
Modified: src Makefile
src/jsrc/org/erights/e/elang/syntax ELexer.java
Indenter.java
src/jsrc/org/erights/e/elib/deflect EventualDeflector.java
src/jsrc/org/erights/e/ui/jed EAction.java
Log:
fixed unmatched close reporting. The 0.8.9zm release
Revision Changes Path
1.114 +2 -2 e/src/Makefile
Index: Makefile
===================================================================
RCS file: /cvs/e/src/Makefile,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -r1.113 -r1.114
--- Makefile 2001/09/04 10:52:17 1.113
+++ Makefile 2001/09/07 18:11:41 1.114
@@ -7,8 +7,8 @@
# Prefix tagging this release's attributes
PREFIX=tl-E
-DOTVER=0.8.9zk
-TAGVER=0_8_9zk
+DOTVER=0.8.9zm
+TAGVER=0_8_9zm
RELEASE=working
TOP=..
1.50 +15 -10 e/src/jsrc/org/erights/e/elang/syntax/ELexer.java
Index: ELexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/ELexer.java,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- ELexer.java 2001/09/07 05:49:22 1.49
+++ ELexer.java 2001/09/07 18:11:41 1.50
@@ -518,9 +518,10 @@
}
return new Token(endToken(), EParser.OpAsr);
}
- Token result = new Token(endToken(), '>');
+ Twine closer = endToken();
+ Token result = new Token(closer, '>');
if (myIndenter.getCloser() == '>') {
- myIndenter.pop('>');
+ myIndenter.pop('>', closer);
return result;
} else {
return continuer(result);
@@ -715,11 +716,13 @@
*
*/
private Token closeBracket() throws IOException {
- char closer = (char)myChar;
+ char closerChar = (char)myChar;
nextChar();
- //throws SyntaxError at open on bad close
- myIndenter.pop(closer);
- return new Token(endToken(), closer);
+ Twine closer = endToken();
+ //on mismatched close, throws SyntaxError at openner
+ //on unmatched close, throws Syntax error at closer
+ myIndenter.pop(closerChar, closer);
+ return new Token(closer, closerChar);
}
/**
@@ -979,8 +982,9 @@
//terminal backquote is eaten but not added to the
//value of the resulting QuasiClose token.
nextChar();
- myIndenter.pop('`');
- return new QuasiPart(endToken(),
+ Twine closer = endToken();
+ myIndenter.pop('`', closer);
+ return new QuasiPart(closer,
EParser.QuasiClose,
buf.toString());
@@ -1074,9 +1078,10 @@
value.append(charConstant());
nextChar();
}
- myIndenter.pop('"');
nextChar();
- return new Literal(endToken(),
+ Twine closer = endToken();
+ myIndenter.pop('"', closer);
+ return new Literal(closer,
EParser.LiteralString,
value.toString());
}
1.3 +15 -15 e/src/jsrc/org/erights/e/elang/syntax/Indenter.java
Index: Indenter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/Indenter.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Indenter.java 2001/09/04 10:52:18 1.2
+++ Indenter.java 2001/09/07 18:11:41 1.3
@@ -112,7 +112,7 @@
* Internal push
*/
private void push(Twine openner,
- char closer,
+ char closerChar,
int indent,
boolean isNest)
{
@@ -124,7 +124,7 @@
myNestStack = (boolean[])grow(myNestStack);
}
myOpennerStack[myTOS] = openner;
- myCloserStack[myTOS] = closer;
+ myCloserStack[myTOS] = closerChar;
myIndentStack[myTOS] = indent;
myNestStack[myTOS] = isNest;
}
@@ -132,16 +132,16 @@
/**
* Push a nester
*/
- public void nest(Twine openner, char closer) {
+ public void nest(Twine openner, char closerChar) {
myNest++;
- push(openner, closer, myNest * 4, true);
+ push(openner, closerChar, myNest * 4, true);
}
/**
* Push a non-nester
*/
- public void push(Twine openner, char closer, int indent) {
- push(openner, closer, indent, false);
+ public void push(Twine openner, char closerChar, int indent) {
+ push(openner, closerChar, indent, false);
}
/**
@@ -149,21 +149,21 @@
* <p>
* If the opening was also a nesting, this decrements the nest level.
*
- * @param closer As an error check, 'closer' must be the closing bracket
- * character needed to close the most recent unclosed
- * bracket.
+ * @param closerChar As an error check, 'closerChar' must be the closing
+ * bracket character needed to close the most recent
+ * unclosed bracket.
*/
- public void pop(char closer) {
+ public void pop(char closerChar, Twine closer) {
if (myTOS <= 0) {
throw new SyntaxException
- ("internal: can't pop empty stack",
- null, 0, 0);
+ ("unmatched closing bracket: " + closerChar,
+ closer, 0, closer.size());
}
- if (myCloserStack[myTOS] != closer) {
+ if (myCloserStack[myTOS] != closerChar) {
Twine openner = myOpennerStack[myTOS];
throw new SyntaxException
- ("mismatch: " + myCloserStack[myTOS] + " vs " + closer,
- openner, 0, openner.size());
+ ("mismatch: " + myCloserStack[myTOS] + " vs " + closerChar,
+ openner, 0, openner.size());
}
int oldTOS = myTOS;
myTOS--;
1.10 +13 -6 e/src/jsrc/org/erights/e/elib/deflect/EventualDeflector.java
Index: EventualDeflector.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/deflect/EventualDeflector.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- EventualDeflector.java 2001/09/07 05:49:22 1.9
+++ EventualDeflector.java 2001/09/07 18:11:41 1.10
@@ -28,19 +28,26 @@
/**
* For deflecting objects that implement EventListener, which hopefully
- * includes all the Listeners in the AWT and Swing frameworks. <p>
- *
+ * includes all the Listeners in the AWT and Swing frameworks.
+ * <p>
* This object "lives" in the vat it which it is created, which it remembers,
* but it can then be J-called outside of this vat. Such J-calls are turned
* into eventual send of a corresponding E-message to the deflected target
- * object, queued for delivery on the originating vat. <p>
- *
+ * object, queued for delivery on the originating vat.
+ * <p>
* Any E-calls must still come from the hosting vat, since these are simply
- * passed through.<p>
- *
+ * passed through.
+ * <p>
* The motivation is to add listeners to various ui widgets, where the
* listeners generally get invoked in some ui thread, but the listener
* objects are written in E, and therefore exist in some vat.
+ * <p>
+ * Because deflected calls are turned into eventual sends, these can only
+ * work when the original call is not expected to return anything.
+ * Therefore, EventualDeflector refuses to deflect calls to methods with
+ * non-void return types. It should do this by refusing to wrap an object
+ * that implements such a method, but XXX currently it instead simply rejects
+ * the invocation.
*
* @author Mark S. Miller
*/
1.8 +30 -18 e/src/jsrc/org/erights/e/ui/jed/EAction.java
Index: EAction.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/ui/jed/EAction.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- EAction.java 2001/09/07 05:49:25 1.7
+++ EAction.java 2001/09/07 18:11:42 1.8
@@ -37,23 +37,34 @@
/**
* Enables an E-language programmer to effectively parameterize an
- * AbstractAction, even though E cannot subclass Java. <p>
- *
+ * {@link AbstractAction}, even though E cannot subclass Java.
+ * <p>
* AbstractAction was designed to be parameterized by subclassing.
* E-language code cannot subclass Java classes, so EAction provides a bridge
* between these issues. EAction is a subclass of AbstractAction whose
* behavior is determined by its properties, which is settable by E language
- * code. <p>
- *
+ * code.
+ * <p>
* In addition, it provides various conveniences absent from Action and
* AbstractAction, such as the ability to use a description string like
* "Save &As" to set the Name ("Save As"), action Verb ("doSaveAs"), and
* mnemonic ('A').
- *
+ * <p>
* The actual action represented by an EAction is the sending of a message
* (verb and arguments) to a recipient. An EAction remembers the vat it was
* created in. When invoked (actionPerformed), it does the does this
* eventual send in its creation vat.
+ * <p>
+ * The E-language programmer must use an EAction in order to "implement" an
+ * {@link javax.swing.Action}, rather than implement Action directly, as
+ * Action violates the {@link org.erights.e.elib.deflect.EventualDeflector}
+ * rules -- it defines methods that have non-void return types. EAction is
+ * therefore an adaptor between the Swing world and the E world. It should
+ * be thought of as an object that lives in the Swing world (and hence uses
+ * <code>synchronized</code> to be thread safe), but knows how to call-back
+ * (or rather, send-back) into the E world. As part of the Swing world, it
+ * also uses to conventional, but dirty and dangerous, practice of
+ * synchronizing on 'this' rather than an encapsulated internal lock.
*
* @author Mark S. Miller
*/
@@ -189,7 +200,7 @@
* For example, 'ea setDesc(foo, "Save &As")' will set the name to "Save
* As", the mnemonic 'A', and the action to be invoked to 'foo <- doSaveAs()'.
*/
- public void setDesc(Object recip, String desc) {
+ public synchronized void setDesc(Object recip, String desc) {
setName(descToName(desc));
setAction(recip, descToVerb(desc));
int mnemonic = descToMnemonic(desc);
@@ -204,7 +215,7 @@
* Does a sendOnly of 'recip <- verb(args...)' in the vat which created
* this EAction.
*/
- public void actionPerformed(ActionEvent e) {
+ public synchronized void actionPerformed(ActionEvent e) {
if (null == myRunner) {
throw new RuntimeException("EActions do not survive revival");
}
@@ -229,7 +240,7 @@
/**
* Sets the action to 'recip <- verb(args...)'
*/
- public void setAction(Object recip, String verb, Object[] args) {
+ public synchronized void setAction(Object recip, String verb, Object[] args) {
myRecip = recip;
myVerb = verb;
myArgs = args;
@@ -238,14 +249,14 @@
/**
* Actually gets the AbstractAction's ACCELERATOR_KEY property.
*/
- public KeyStroke getAccelerator() {
+ public synchronized KeyStroke getAccelerator() {
return (KeyStroke)getValue(ACCELERATOR_KEY);
}
/**
* Actually sets the AbstractAction's ACCELERATOR_KEY property.
*/
- public void setAccelerator(KeyStroke newKey) {
+ public synchronized void setAccelerator(KeyStroke newKey) {
putValue(ACCELERATOR_KEY, newKey);
}
@@ -288,21 +299,21 @@
/**
* Actually gets the AbstractAction's NAME property.
*/
- public String getName() {
+ public synchronized String getName() {
return (String)getValue(NAME);
}
/**
* Actually sets the AbstractAction's NAME property.
*/
- public void setName(String newName) {
+ public synchronized void setName(String newName) {
putValue(NAME, newName);
}
/**
* Actually gets the AbstractAction's MNEMONIC_KEY property.
*/
- public int getMnemonic() {
+ public synchronized int getMnemonic() {
Object val = getValue(MNEMONIC_KEY);
if (null == val) {
return -1;
@@ -314,7 +325,7 @@
/**
* Actually sets the AbstractAction's MNEMONIC_KEY property.
*/
- public void setMnemonic(int newMnemonic) {
+ public synchronized void setMnemonic(int newMnemonic) {
if (-1 == newMnemonic) {
putValue(MNEMONIC_KEY, null);
} else {
@@ -325,21 +336,22 @@
/**
* Actually gets the AbstractAction's SHORT_DESCRIPTION property.
*/
- public String getTip() {
+ public synchronized String getTip() {
return (String)getValue(SHORT_DESCRIPTION);
}
/**
* Actually sets the AbstractAction's SHORT_DESCRIPTION property.
*/
- public void setTip(String newTip) {
+ public synchronized void setTip(String newTip) {
putValue(SHORT_DESCRIPTION, newTip);
}
/**
- *
+ * This method is purely for use from the E world, but it's synchronized
+ * since it accesses state that may be mutated by either world.
*/
- public void printOn(TextWriter out) throws IOException {
+ public synchronized void printOn(TextWriter out) throws IOException {
out.print("<- ", myVerb);
Object[] keys = getKeys();
if (null == keys) {