changeset 1465:a5521ef3db10

Lambda compilation: simplification, documentation, and clean-up
author robert.field@oracle.com
date Fri, 28 Sep 2012 15:42:02 -0700
parents 0e71dd95f7ef
children b0aefe629755
files src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
diffstat 1 files changed, 101 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed Sep 26 22:29:05 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Sep 28 15:42:02 2012 -0700
@@ -252,12 +252,16 @@
         }
     }
 
+    /**
+     * Translate identifiers within a lambda to the mapped identifier
+     * @param tree 
+     */
     @Override
     public void visitIdent(JCIdent tree) {
-        LambdaToMethodTranslationContext lambdaContext = (LambdaToMethodTranslationContext)context;
         if (context == null || !analyzer.lambdaIdentSymbolFilter(tree.sym)) {
             super.visitIdent(tree);
         } else {
+            LambdaToMethodTranslationContext lambdaContext = (LambdaToMethodTranslationContext) context;
             if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) {
                 Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym);
                 result = make.Ident(translatedSym).setType(tree.type);
@@ -302,12 +306,16 @@
 
     // <editor-fold defaultstate="collapsed" desc="Translation helper methods">
     
+    /**
+     * Generate an adapter method "bridge" for a method reference which cannot
+     * be used directly.
+     */
     private class MemberReferenceBridger {
 
-        final JCMemberReference tree;
-        final ReferenceToMethodTranslationContext localContext;
-        ListBuffer<JCExpression> args = ListBuffer.lb();
-        ListBuffer<JCVariableDecl> params = ListBuffer.lb();
+        private final JCMemberReference tree;
+        private final ReferenceToMethodTranslationContext localContext;
+        private final ListBuffer<JCExpression> args = ListBuffer.lb();
+        private final ListBuffer<JCVariableDecl> params = ListBuffer.lb();
 
         MemberReferenceBridger(JCMemberReference tree, ReferenceToMethodTranslationContext localContext) {
             this.tree = tree;
@@ -315,68 +323,8 @@
         }
 
         /**
-         * determine the receiver of the bridged method call - the receiver can
-         * be either the synthetic receiver parameter or a type qualifier; the
-         * original qualifier expression is never used here, as it might refer
-         * to symbols not available in the static context of the bridge
+         * Generate the bridge 
          */
-        JCExpression bridgeExpressionInvoke(VarSymbol rcvr) {
-            JCExpression qualifier =
-                    tree.sym.isStatic() ? 
-                        make.Type(tree.sym.owner.type) : 
-                        (rcvr != null) ? 
-                            make.Ident(rcvr) : 
-                            tree.getQualifierExpression();
- 
-            //create the qualifier expression
-            JCFieldAccess select = make.Select(qualifier, tree.sym.name);
-            select.sym = tree.sym;
-            select.type = tree.sym.erasure(types);
-
-            //create the method call expression
-            JCExpression apply = make.Apply(List.<JCExpression>nil(), select,
-                    convertArgs(tree.sym, args.toList(), tree.varargsElement)).setType(tree.sym.erasure(types).getReturnType());
-
-            apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType());
-            setVarargsIfNeeded(apply, tree.varargsElement);
-            return apply;
-        }
-
-        /**
-         * the enclosing expression is either 'null' (no enclosing type) or set
-         * to the first bridge synthetic parameter
-         */
-        JCExpression bridgeExpressionNew() {
-            JCExpression encl = null;
-            switch (tree.kind) {
-                case UNBOUND:
-                case UNBOUND_INNER:
-                case IMPLICIT_INNER:
-                    encl = make.Ident(params.first());
-            }
-
-            //create the instance creation expression
-            JCNewClass newClass = make.NewClass(encl,
-                    List.<JCExpression>nil(),
-                    make.Type(tree.getQualifierExpression().type),
-                    convertArgs(tree.sym, args.toList(), tree.varargsElement),
-                    null);
-            newClass.constructor = tree.sym;
-            newClass.constructorType = tree.sym.erasure(types);
-            newClass.type = tree.getQualifierExpression().type;
-            setVarargsIfNeeded(newClass, tree.varargsElement);
-            return newClass;
-        }
-
-        VarSymbol addParameter(String name, Type p, boolean genArg) {
-            VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym);
-            params.append(make.VarDef(vsym, null));
-            if (genArg) {
-                args.append(make.Ident(vsym));
-            }
-            return vsym;
-        }
-
         JCMethodDecl bridge() {
             int prevPos = make.pos;
             try {
@@ -455,6 +403,69 @@
                 make.at(prevPos);
             }    
         }
+
+        /**
+         * determine the receiver of the bridged method call - the receiver can
+         * be either the synthetic receiver parameter or a type qualifier; the
+         * original qualifier expression is never used here, as it might refer
+         * to symbols not available in the static context of the bridge
+         */
+        private JCExpression bridgeExpressionInvoke(VarSymbol rcvr) {
+            JCExpression qualifier =
+                    tree.sym.isStatic() ? 
+                        make.Type(tree.sym.owner.type) : 
+                        (rcvr != null) ? 
+                            make.Ident(rcvr) : 
+                            tree.getQualifierExpression();
+ 
+            //create the qualifier expression
+            JCFieldAccess select = make.Select(qualifier, tree.sym.name);
+            select.sym = tree.sym;
+            select.type = tree.sym.erasure(types);
+
+            //create the method call expression
+            JCExpression apply = make.Apply(List.<JCExpression>nil(), select,
+                    convertArgs(tree.sym, args.toList(), tree.varargsElement)).setType(tree.sym.erasure(types).getReturnType());
+
+            apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType());
+            setVarargsIfNeeded(apply, tree.varargsElement);
+            return apply;
+        }
+
+        /**
+         * the enclosing expression is either 'null' (no enclosing type) or set
+         * to the first bridge synthetic parameter
+         */
+        private JCExpression bridgeExpressionNew() {
+            JCExpression encl = null;
+            switch (tree.kind) {
+                case UNBOUND:
+                case UNBOUND_INNER:
+                case IMPLICIT_INNER:
+                    encl = make.Ident(params.first());
+            }
+
+            //create the instance creation expression
+            JCNewClass newClass = make.NewClass(encl,
+                    List.<JCExpression>nil(),
+                    make.Type(tree.getQualifierExpression().type),
+                    convertArgs(tree.sym, args.toList(), tree.varargsElement),
+                    null);
+            newClass.constructor = tree.sym;
+            newClass.constructorType = tree.sym.erasure(types);
+            newClass.type = tree.getQualifierExpression().type;
+            setVarargsIfNeeded(newClass, tree.varargsElement);
+            return newClass;
+        }
+
+        private VarSymbol addParameter(String name, Type p, boolean genArg) {
+            VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym);
+            params.append(make.VarDef(vsym, null));
+            if (genArg) {
+                args.append(make.Ident(vsym));
+            }
+            return vsym;
+        }
     }
 
     /**
@@ -564,7 +575,10 @@
     }
     // </editor-fold>
 
-    // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">
+    // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">\
+    /**
+     * Analyze 
+     */
     class LambdaToMethodAnalyzer extends LambdaAnalyzer {
 
         /**
@@ -606,7 +620,7 @@
 
         @Override
         public void visitNewClass(JCNewClass tree) {
-            if (new LambdaNewClassFilter(context()).accepts(tree)) {
+            if (lambdaNewClassFilter(context(), tree)) {
                 ((LambdaTranslationContext) context()).addSymbol(tree.type.getEnclosingType().tsym, CAPTURED_THIS);
             }
             super.visitNewClass(tree);
@@ -616,7 +630,6 @@
         protected boolean lambdaIdentSymbolFilter(Symbol sym) {
             return (sym.kind == VAR || sym.kind == MTH)
                     && !sym.isStatic()
-                 // && sym.name != names._super // Unlike LambdaTranslator, we need to know about super references
                     && sym.name != names.init;
         }
         
@@ -628,16 +641,16 @@
                         sym.name == names._super); // Unlike LambdaTranslator, we need to know about super references
         }
 
-        abstract class LambdaToMethodFilter<T extends JCTree> implements Filter<T> {
-
-            TranslationContext<?> context;
-
-            LambdaToMethodFilter(TranslationContext<?> context) {
-                this.context = context;
-            }
-
-            protected boolean hasEnclosingInstance(Type ctype) {
-                Type encl = ctype.getEnclosingType();
+        /**
+         * This is used to filter out those new class expressions that need to
+         * be qualified with an enclosing tree
+         */
+        private boolean lambdaNewClassFilter(TranslationContext<?> context, JCNewClass tree) {
+            if (context != null
+                    && tree.encl == null
+                    && tree.def == null
+                    && tree.type.getEnclosingType().tag != TypeTags.NONE) {
+                Type encl = tree.type.getEnclosingType();
                 Type current = context.owner.enclClass().type;
                 while (current.tag != TypeTags.NONE) {
                     if (current.tsym.isSubClass(encl.tsym, types)) {
@@ -646,29 +659,11 @@
                     current = current.getEnclosingType();
                 }
                 return false;
+            } else {
+                return false;
             }
         }
-
-        /**
-         * This is used to filter out those new class expressions that need to
-         * be qualified with an enclosing tree
-         */
-        protected final class LambdaNewClassFilter extends LambdaToMethodFilter<JCNewClass> {
-
-            LambdaNewClassFilter(TranslationContext<?> context) {
-                super(context);
-            }
-
-            @Override
-            public boolean accepts(JCNewClass tree) {
-                return tree.encl == null
-                        && tree.def == null
-                        && tree.type.getEnclosingType().tag != TypeTags.NONE
-                        && context != null
-                        && hasEnclosingInstance(tree.type);
-            }
-        };
-
+        
         class LambdaToMethodTranslationContext extends LambdaTranslationContext {
             
             List<JCVariableDecl> syntheticParams;
@@ -687,6 +682,12 @@
                 }
             }
             
+            /**
+             * The translatedSym is not complete/accurate until the analysis is 
+             * finished.  Once the analysis is finished, the translatedSym is
+             * "completed" -- updated with type information, access modifiers,
+             * and full parameter list.
+             */
             void complete() {
                 if (syntheticParams != null) {
                     return;