[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) {