1 19 package org.netbeans.modules.java.source.builder; 20 21 import com.sun.tools.javac.code.Flags; 22 import com.sun.tools.javac.code.Scope; 23 import com.sun.tools.javac.code.Type; 24 import com.sun.tools.javac.code.TypeTags; 25 import javax.lang.model.element.TypeElement; 26 import javax.lang.model.type.ExecutableType; 27 import org.netbeans.api.java.source.*; 28 import org.netbeans.modules.java.source.engine.ASTModel; 29 import com.sun.source.util.TreeScanner; 30 31 import com.sun.source.tree.*; 32 import com.sun.source.tree.Tree.Kind; 33 import com.sun.tools.javac.code.Kinds; 34 import com.sun.tools.javac.tree.JCTree.*; 35 import com.sun.tools.javac.code.Symbol; 36 import com.sun.tools.javac.code.Symbol.*; 37 import com.sun.tools.javac.tree.JCTree; 38 import com.sun.tools.javac.util.*; 39 import javax.lang.model.util.Types; 40 41 import java.util.HashMap ; 42 43 class VariableCharacterization { 44 public static final int ASSIGN = 1<<0; 45 public static final int REFERENCE = 1<<1; 46 public static final int IDENT = 1<<2; 47 public static final int SELECT = 1<<3; 48 public static final int DECLARE = 1<<4; 49 public static final int PARAMETER = 1<<5; 50 51 int thisUseCount; 52 private int allflags; 53 private int allnotflags; 54 final HashMap <Object ,CNode> map = new HashMap <Object ,CNode>(); 55 56 public VariableCharacterization(Tree t, final ASTModel model, final ElementsService elements) { 57 new TreeScanner<Void ,Tree>() { 58 TypeSymbol owner = null; 59 public Void visitIdentifier(IdentifierTree tree, Tree parent) { 60 JCIdent t = (JCIdent)tree; 61 Symbol sym = t.sym; 62 checkBoth(t.name, sym, IDENT | parentContext(tree, parent)); 63 if(model.isThis(t) || sym!=null && (sym.kind & (Kinds.PCK | Kinds.TYP)) == 0 && !sym.isLocal()) 64 thisUseCount++; 65 return null; 66 } 67 public Void visitMemberSelect(MemberSelectTree tree, Tree parent) { 68 JCFieldAccess t = (JCFieldAccess)tree; 69 checkBoth(t.name, t.sym, SELECT|parentContext(tree, parent)); 70 if(isThis(t.name)) thisUseCount++; super.visitMemberSelect(tree, parent); 72 return null; 73 } 74 public Void visitNewClass(NewClassTree tree, Tree parent) { 75 checkBoth(null, ((JCNewClass)tree).constructor, 0); 76 super.visitNewClass(tree, parent); 77 return null; 78 } 79 public Void visitVariable(VariableTree tree, Tree parent) { 80 int flags = DECLARE; 81 if(parent!=null && (parent.getKind() == Kind.METHOD || parent.getKind() == Kind.CATCH)) 82 flags|=PARAMETER; 83 JCVariableDecl t = (JCVariableDecl)tree; 84 checkBoth(t.name, t.sym, flags); 85 super.visitVariable(tree, parent); 86 return null; 87 } 88 public Void visitMethod(MethodTree tree, Tree parent) { 89 TypeSymbol oldOwner = owner; 90 JCMethodDecl t = (JCMethodDecl)tree; 91 if (t.sym != null) 92 owner = (TypeSymbol) t.sym.owner; 93 super.visitMethod(tree, parent); 94 owner = oldOwner; 95 return null; 96 } 97 public Void visitClass(ClassTree tree, Tree parent) { 98 TypeSymbol oldOwner = owner; 99 JCClassDecl t = (JCClassDecl)tree; 100 if (t.sym != null && t.sym.owner instanceof TypeSymbol) 101 owner = (TypeSymbol) t.sym.owner; 102 super.visitClass(tree, parent); 103 owner = oldOwner; 104 return null; 105 } 106 int parentContext(Tree tree, Tree parent) { 107 if(parent==null) return 0; 108 int tag = ((JCTree)parent).tag; 109 if(JCTree.BITOR_ASG<=tag && tag<=JCTree.MOD_ASG) { 110 if(((JCAssignOp)parent).lhs==tree) return ASSIGN; 111 } 112 else if(tag==JCTree.ASSIGN && ((JCAssign)parent).lhs==tree) return ASSIGN; 113 return REFERENCE; 114 } 115 private void checkBoth(Name name, Symbol sym, int flags) { 116 if(name!=null) checkOne(name, flags); 117 if(sym!=null && checkOne(sym, flags) && 118 sym.owner!=null && !sym.isLocal() && owner!=null) { 119 121 if(elements.isMemberOf(sym, (TypeElement)owner)) { 122 long sflags = sym.flags(); 123 allflags |= sflags; 124 allnotflags |= ~sflags; 125 } 126 } 127 } 128 private boolean checkOne(Object key, int flags) { 129 CNode c = map.get(key); 130 if(c==null) { 131 map.put(key,c=new CNode()); 132 c.usage |= flags; 133 c.useCount++; 134 return true; 135 } 136 c.useCount++; 137 c.usage |= flags; 138 return false; 139 } 140 private boolean isThis(Name nm) { 141 return nm==nm.table._this; 142 } 143 }.scan(t, null); 144 } 145 146 public final int usage(Object s) { 147 CNode cn = map.get(s); 148 return cn==null ? 0 : cn.usage; 149 } 150 151 public final int useCount(Object s) { 152 CNode cn = map.get(s); 153 return cn==null ? 0 : cn.useCount; 154 } 155 156 public final boolean assigned(Object s) { 157 return (usage(s)&ASSIGN)!=0; 158 } 159 160 public final boolean referenced(Object s) { 161 return (usage(s)&REFERENCE)!=0; 162 } 163 164 public final boolean ident(Object s) { 165 return (usage(s)&IDENT)!=0; 166 } 167 168 public final boolean selected(Object s) { 169 return (usage(s)&SELECT)!=0; 170 } 171 172 public final boolean declared(Object s) { 173 return (usage(s)&DECLARE)!=0; 174 } 175 176 public final boolean parameter(Object s) { 177 return (usage(s)&PARAMETER)!=0; 178 } 179 180 public final int getThisUseCount() { 181 return thisUseCount; 182 } 183 184 public final int getAllFlags() { 185 return allflags; 186 } 187 188 public final int getAllNotFlags() { 189 return allnotflags; 190 } 191 192 private static class CNode { 193 int usage; 194 int useCount = 0; 195 } 196 } 197 | Popular Tags |