Fwd: Right direction?

Matthias Ernst ernst.matthias at gmail.com
Sat May 26 06:19:39 PDT 2007


Hi,

I've created an experimental feature, namely cascading for void method
calls as described on my blog @ http://mernst.org/blog/rss.xml
(Firefox only :-(  Patches at the end, too.

I would be glad to hear some comments what you think about the patches
(not the semantics but the implementation) - did I miss something? A
hint how I would find out the receiver type for unqualified method
calls without duplicating the lookup strategy in Attr#visitApply would
be appreciated, too!


Thanks
Matthias



--- comp/Attr.java.orig.txt     2007-05-26 13:55:53.000000000 +0200
+++ comp/Attr.java      2007-05-26 14:15:51.000000000 +0200
@@ -1315,6 +1315,18 @@
                               restype.tsym);
             }
+            // as a special case, o.m() where m is a void method, has type of o
+            if(restype == Symtab.voidType &&
!isStatic(TreeInfo.symbol(tree.meth))) {
+                if(tree.meth.tag != JCTree.SELECT) {
+                    log.warning(tree.meth.pos(), "Cannot (yet)
cascade unqualified method call");
+                } else {
+                    JCExpression receiver = ((JCFieldAccess)
tree.meth).selected;
+                    restype = receiver.type;
+                }
+            }
+
+
+
             // Check that value of resulting type is admissible in the
             // current context.  Also, capture the return type
             result = check(tree, capture(restype), VAL, pkind, pt);

--- comp/TransTypes.java.orig.txt       2007-05-26 13:56:46.000000000 +0200
+++ comp/TransTypes.java        2007-05-26 14:15:51.000000000 +0200
@@ -583,7 +587,8 @@
         tree.args = translateArgs(tree.args, argtypes, tree.varargsElement);

         // Insert casts of method invocation results as needed.
-        result = retype(tree, mt.getReturnType(), pt);
+        // mernst: do not use mt.resType as cascading may have changed it
+        result = retype(tree, types.erasure(tree.type), pt);
     }

     public void visitNewClass(JCNewClass tree) {

--- jvm/Gen.java.orig.txt       2007-05-26 14:00:07.000000000 +0200
+++ jvm/Gen.java        2007-05-26 14:16:38.000000000 +0200
@@ -1664,14 +1664,24 @@
  *************************************************************************/

     public void visitApply(JCMethodInvocation tree) {
+
        // Generate code for method.
        Item m = genExpr(tree.meth, methodType);
+
+        // in case of a cascade, duplicate the receiver
+        boolean cascaded = ((MethodType)tree.meth.type).restype ==
Symtab.voidType && tree.type != Symtab.voidType;
+        Item stackItem = cascaded ? items.makeStackItem(tree.type) : null;
+        if(cascaded) stackItem.duplicate();
+
        // Generate code for all arguments, where the expected types are
        // the parameters of the method's external type (that is, any implicit
        // outer instance of a super(...) call appears as first parameter).
        genArgs(tree.args,

TreeInfo.symbol(tree.meth).externalType(types).getParameterTypes());
        result = m.invoke();
+
+        // in case of a cascade, the receiver is top of stack now
+        if(cascaded) result = stackItem;
     }

     public void visitConditional(JCConditional tree) {



More information about the compiler-dev mailing list