Coverage Report - com.sun.tools.javafx.api.JavafxcTrees
 
Classes in this File Line Coverage Branch Coverage Complexity
JavafxcTrees
22%
25/114
3%
2/60
0
JavafxcTrees$1
100%
4/4
N/A
0
JavafxcTrees$1PathFinder
100%
4/4
100%
2/2
0
JavafxcTrees$1Result
100%
3/3
N/A
0
JavafxcTrees$2
0%
0/1
N/A
0
JavafxcTrees$Copier
0%
0/8
0%
0/2
0
 
 1  
 /*
 2  
  * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
 3  
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  
  *
 5  
  * This code is free software; you can redistribute it and/or modify it
 6  
  * under the terms of the GNU General Public License version 2 only, as
 7  
  * published by the Free Software Foundation.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun in the LICENSE file that accompanied this code.
 10  
  *
 11  
  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  
  * version 2 for more details (a copy is included in the LICENSE file that
 15  
  * accompanied this code).
 16  
  *
 17  
  * You should have received a copy of the GNU General Public License version
 18  
  * 2 along with this work; if not, write to the Free Software Foundation,
 19  
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  
  *
 21  
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.tools.javafx.api;
 27  
 
 28  
 import com.sun.javafx.api.*;
 29  
 import com.sun.javafx.api.tree.ClassDeclarationTree;
 30  
 import com.sun.javafx.api.tree.JavaFXTreePathScanner;
 31  
 import com.sun.javafx.api.tree.FunctionDefinitionTree;
 32  
 import java.io.IOException;
 33  
 import java.util.Map;
 34  
 import javax.lang.model.element.Element;
 35  
 import javax.lang.model.element.ExecutableElement;
 36  
 import javax.lang.model.element.TypeElement;
 37  
 import javax.lang.model.type.DeclaredType;
 38  
 import javax.lang.model.type.TypeMirror;
 39  
 import javax.tools.JavaFileObject;
 40  
 
 41  
 import com.sun.source.tree.CompilationUnitTree;
 42  
 import com.sun.source.tree.Scope;
 43  
 import com.sun.source.tree.Tree;
 44  
 import com.sun.source.util.SourcePositions;
 45  
 import com.sun.source.util.TreePath;
 46  
 import com.sun.tools.javac.code.Kinds;
 47  
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 48  
 import com.sun.tools.javac.code.Symbol.TypeSymbol;
 49  
 import com.sun.tools.javac.code.Symbol;
 50  
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
 51  
 import com.sun.tools.javac.comp.Attr;
 52  
 import com.sun.tools.javac.comp.AttrContext;
 53  
 import com.sun.tools.javac.comp.Enter;
 54  
 import com.sun.tools.javac.comp.Env;
 55  
 import com.sun.tools.javac.comp.MemberEnter;
 56  
 import com.sun.tools.javac.comp.Resolve;
 57  
 import com.sun.tools.javac.tree.JCTree.*;
 58  
 import com.sun.tools.javac.tree.JCTree;
 59  
 import com.sun.tools.javac.tree.TreeCopier;
 60  
 import com.sun.tools.javac.tree.TreeInfo;
 61  
 import com.sun.tools.javac.tree.TreeMaker;
 62  
 import com.sun.tools.javac.util.Context;
 63  
 import com.sun.tools.javac.util.List;
 64  
 import com.sun.tools.javac.util.Log;
 65  
 import com.sun.tools.javac.util.Pair;
 66  
 import com.sun.tools.javafx.tree.JavafxTreeInfo;
 67  
 
 68  
 /**
 69  
  * Provides an implementation of Trees for the JavaFX Script compiler, based
 70  
  * on JavacTrees.
 71  
  *
 72  
  * @author Peter von der Ahé
 73  
  * @author Tom Ball
 74  
  */
 75  
 public class JavafxcTrees {
 76  
 
 77  
     private final Resolve resolve;
 78  
     private final Enter enter;
 79  
     private final Log log;
 80  
     private final MemberEnter memberEnter;
 81  
     private final Attr attr;
 82  
     private final TreeMaker treeMaker;
 83  
     private final JavafxcTaskImpl javafxcTaskImpl;
 84  
 
 85  
     public static JavafxcTrees instance(JavafxCompiler.CompilationTask task) {
 86  4
         if (!(task instanceof JavafxcTaskImpl))
 87  0
             throw new IllegalArgumentException();
 88  4
         return instance(((JavafxcTaskImpl)task).getContext());
 89  
     }
 90  
 
 91  
     public static JavafxcTrees instance(Context context) {
 92  4
         JavafxcTrees instance = context.get(JavafxcTrees.class);
 93  4
         if (instance == null)
 94  4
             instance = new JavafxcTrees(context);
 95  4
         return instance;
 96  
     }
 97  
 
 98  4
     private JavafxcTrees(Context context) {
 99  4
         context.put(JavafxcTrees.class, this);
 100  4
         attr = Attr.instance(context);
 101  4
         enter = Enter.instance(context);
 102  4
         log = Log.instance(context);
 103  4
         resolve = Resolve.instance(context);
 104  4
         treeMaker = TreeMaker.instance(context);
 105  4
         memberEnter = MemberEnter.instance(context);
 106  4
         javafxcTaskImpl = context.get(JavafxcTaskImpl.class);
 107  4
     }
 108  
 
 109  
     public SourcePositions getSourcePositions() {
 110  4
         return new SourcePositions() {
 111  
                 public long getStartPosition(CompilationUnitTree file, Tree tree) {
 112  6
                     return JavafxTreeInfo.getStartPos((JCTree) tree);
 113  
                 }
 114  
 
 115  
                 public long getEndPosition(CompilationUnitTree file, Tree tree) {
 116  5
                     Map<JCTree,Integer> endPositions = ((JCCompilationUnit) file).endPositions;
 117  5
                     return JavafxTreeInfo.getEndPos((JCTree) tree, endPositions);
 118  
                 }
 119  
             };
 120  
     }
 121  
 
 122  
     public ClassDeclarationTree getTree(TypeElement element) {
 123  0
         return (ClassDeclarationTree) getTree((Element) element);
 124  
     }
 125  
 
 126  
     public FunctionDefinitionTree getTree(ExecutableElement method) {
 127  0
         return (FunctionDefinitionTree) getTree((Element) method);
 128  
     }
 129  
 
 130  
     public Tree getTree(Element element) {
 131  0
         Symbol symbol = (Symbol) element;
 132  0
         TypeSymbol enclosing = symbol.enclClass();
 133  0
         Env<AttrContext> env = enter.getEnv(enclosing);
 134  0
         if (env == null)
 135  0
             return null;
 136  0
         JCClassDecl classNode = env.enclClass;
 137  0
         if (classNode != null) {
 138  0
             if (JavafxTreeInfo.symbolFor(classNode) == element)
 139  0
                 return classNode;
 140  0
             for (JCTree node : classNode.getMembers())
 141  0
                 if (JavafxTreeInfo.symbolFor(node) == element)
 142  0
                     return node;
 143  
         }
 144  0
         return null;
 145  
     }
 146  
 
 147  
     public TreePath getPath(CompilationUnitTree unit, Tree node) {
 148  2
         return getPath(new TreePath(unit), node);
 149  
     }
 150  
 
 151  
     public TreePath getPath(Element e) {
 152  0
         final Pair<JCTree, JCCompilationUnit> treeTopLevel = getTreeAndTopLevel(e);
 153  0
         if (treeTopLevel == null)
 154  0
             return null;
 155  0
         return getPath(treeTopLevel.snd, treeTopLevel.fst);
 156  
     }
 157  
     
 158  
     /**
 159  
      * Gets a tree path for a tree node within a subtree identified by a TreePath object.
 160  
      * @return null if the node is not found
 161  
      */
 162  
     public static TreePath getPath(TreePath path, Tree target) {
 163  2
         path.getClass();
 164  2
         target.getClass();
 165  
 
 166  
         class Result extends Error {
 167  
             static final long serialVersionUID = -5942088234594905625L;
 168  
             TreePath path;
 169  2
             Result(TreePath path) {
 170  2
                 this.path = path;
 171  2
             }
 172  
         }
 173  41
         class PathFinder extends JavaFXTreePathScanner<TreePath,Tree> {
 174  
             public TreePath scan(Tree tree, Tree target) {
 175  39
                 if (tree == target)
 176  2
                     throw new Result(new TreePath(getCurrentPath(), target));
 177  37
                 return super.scan(tree, target);
 178  
             }
 179  
         }
 180  
 
 181  
         try {
 182  2
             new PathFinder().scan(path, target);
 183  2
         } catch (Result result) {
 184  2
             return result.path;
 185  0
         }
 186  0
         return null;
 187  
     }
 188  
 
 189  
     public Element getElement(TreePath path) {
 190  2
         Tree t = path.getLeaf();
 191  2
         return JavafxTreeInfo.symbolFor((JCTree) t);
 192  
     }
 193  
 
 194  
     public TypeMirror getTypeMirror(TreePath path) {
 195  0
         Tree t = path.getLeaf();
 196  0
         return ((JCTree)t).type;
 197  
     }
 198  
 
 199  
     public JavafxcScope getScope(TreePath path) {
 200  0
         return new JavafxcScope(getAttrContext(path));
 201  
     }
 202  
 
 203  
     public boolean isAccessible(Scope scope, TypeElement type) {
 204  0
         if (scope instanceof JavafxcScope && type instanceof ClassSymbol) {
 205  0
             Env<AttrContext> env = ((JavafxcScope) scope).env;
 206  0
             return resolve.isAccessible(env, (ClassSymbol)type);
 207  
         } else
 208  0
             return false;
 209  
     }
 210  
 
 211  
     public boolean isAccessible(Scope scope, Element member, DeclaredType type) {
 212  0
         if (scope instanceof JavafxcScope
 213  
                 && member instanceof Symbol
 214  
                 && type instanceof com.sun.tools.javac.code.Type) {
 215  0
             Env<AttrContext> env = ((JavafxcScope) scope).env;
 216  0
             return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member);
 217  
         } else
 218  0
             return false;
 219  
     }
 220  
 
 221  
     private Env<AttrContext> getAttrContext(TreePath path) {
 222  0
         if (!(path.getLeaf() instanceof JCTree))  // implicit null-check
 223  0
             throw new IllegalArgumentException();
 224  
 
 225  
         // if we're being invoked via from a JSR199 client, we need to make sure
 226  
         // all the classes have been entered; if we're being invoked from JSR269,
 227  
         // then the classes will already have been entered.
 228  0
         if (javafxcTaskImpl != null) {
 229  
             try {
 230  0
                 javafxcTaskImpl.enter();
 231  0
             } catch (IOException e) {
 232  0
                 throw new Error("unexpected error while entering symbols: " + e);
 233  0
             }
 234  
         }
 235  
 
 236  
 
 237  0
         JCCompilationUnit unit = (JCCompilationUnit) path.getCompilationUnit();
 238  0
         Copier copier = new Copier(treeMaker.forToplevel(unit));
 239  
 
 240  0
         Env<AttrContext> env = null;
 241  0
         JCMethodDecl method = null;
 242  0
         JCVariableDecl field = null;
 243  
 
 244  0
         List<Tree> l = List.nil();
 245  0
         TreePath p = path;
 246  0
         while (p != null) {
 247  0
             l = l.prepend(p.getLeaf());
 248  0
             p = p.getParentPath();
 249  
         }
 250  
 
 251  0
         for ( ; l.nonEmpty(); l = l.tail) {
 252  0
             Tree tree = l.head;
 253  0
             switch (tree.getKind()) {
 254  
                 case COMPILATION_UNIT:
 255  
 //                    System.err.println("COMP: " + ((JCCompilationUnit)tree).sourcefile);
 256  0
                     env = enter.getTopLevelEnv((JCCompilationUnit)tree);
 257  0
                     break;
 258  
                 case CLASS:
 259  
 //                    System.err.println("CLASS: " + ((JCClassDecl)tree).sym.getSimpleName());
 260  0
                     env = enter.getClassEnv(((JCClassDecl)tree).sym);
 261  0
                     break;
 262  
                 case METHOD:
 263  
 //                    System.err.println("METHOD: " + ((JCMethodDecl)tree).sym.getSimpleName());
 264  0
                     method = (JCMethodDecl)tree;
 265  0
                     break;
 266  
                 case VARIABLE:
 267  
 //                    System.err.println("FIELD: " + ((JCVariableDecl)tree).sym.getSimpleName());
 268  0
                     field = (JCVariableDecl)tree;
 269  0
                     break;
 270  
                 case BLOCK: {
 271  
 //                    System.err.println("BLOCK: ");
 272  0
                     if (method != null)
 273  0
                         env = memberEnter.getMethodEnv(method, env);
 274  0
                     JCTree body = copier.copy((JCTree)tree, (JCTree) path.getLeaf());
 275  0
                     env = attribStatToTree(body, env, copier.leafCopy);
 276  0
                     return env;
 277  
                 }
 278  
                 default:
 279  
 //                    System.err.println("DEFAULT: " + tree.getKind());
 280  0
                     if (field != null && field.getInitializer() == tree) {
 281  0
                         env = memberEnter.getInitEnv(field, env);
 282  0
                         JCExpression expr = copier.copy((JCExpression)tree, (JCTree) path.getLeaf());
 283  0
                         env = attribExprToTree(expr, env, copier.leafCopy);
 284  0
                         return env;
 285  
                     }
 286  
             }
 287  
         }
 288  0
         return field != null ? memberEnter.getInitEnv(field, env) : env;
 289  
     }
 290  
 
 291  
     private Env<AttrContext> attribStatToTree(JCTree stat, Env<AttrContext>env, JCTree tree) {
 292  0
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 293  
         try {
 294  0
             return attr.attribStatToTree(stat, env, tree);
 295  
         } finally {
 296  0
             log.useSource(prev);
 297  
         }
 298  
     }
 299  
 
 300  
     private Env<AttrContext> attribExprToTree(JCExpression expr, Env<AttrContext>env, JCTree tree) {
 301  0
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 302  
         try {
 303  0
             return attr.attribExprToTree(expr, env, tree);
 304  
         } finally {
 305  0
             log.useSource(prev);
 306  
         }
 307  
     }
 308  
     
 309  
     private Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel(Element e) {
 310  0
         if (e == null)
 311  0
             return null;
 312  
 
 313  0
         Symbol sym = (Symbol)e;
 314  0
         TypeSymbol ts = (sym.kind != Kinds.PCK)
 315  
                         ? sym.enclClass()
 316  
                         : (PackageSymbol) sym;
 317  0
         Env<AttrContext> enterEnv = ts != null ? enter.getEnv(ts) : null;        
 318  0
         if (enterEnv == null)
 319  0
             return null;
 320  
         
 321  0
         JCTree tree = JavafxTreeInfo.declarationFor(sym, enterEnv.tree);
 322  0
         if (tree == null || enterEnv.toplevel == null)
 323  0
             return null;
 324  0
         return new Pair<JCTree,JCCompilationUnit>(tree, enterEnv.toplevel);
 325  
     }
 326  
 
 327  
     /**
 328  
      * Makes a copy of a tree, noting the value resulting from copying a particular leaf.
 329  
      **/
 330  0
     static class Copier extends TreeCopier<JCTree> {
 331  0
         JCTree leafCopy = null;
 332  
 
 333  
         Copier(TreeMaker M) {
 334  0
             super(M);
 335  0
         }
 336  
 
 337  
         @Override
 338  
         public <T extends JCTree> T copy(T t, JCTree leaf) {
 339  0
             T t2 = super.copy(t, leaf);
 340  0
             if (t == leaf)
 341  0
                 leafCopy = t2;
 342  0
             return t2;
 343  
         }
 344  
     }
 345  
 }