1 19 20 package org.netbeans.modules.java.source.builder; 21 22 import com.sun.source.tree.Tree; 23 import com.sun.source.util.Trees; 24 import com.sun.tools.javac.api.JavacTrees; 25 import com.sun.tools.javac.code.Flags; 26 import com.sun.tools.javac.util.Name; 27 import javax.lang.model.util.Types; 28 import org.netbeans.api.java.source.*; 29 import com.sun.tools.javac.code.Scope; 30 import com.sun.tools.javac.code.Symbol; 31 import com.sun.tools.javac.code.Symbol.ClassSymbol; 32 import com.sun.tools.javac.code.Symbol.MethodSymbol; 33 import com.sun.tools.javac.code.Symbol.TypeSymbol; 34 import com.sun.tools.javac.code.Type; 35 import com.sun.tools.javac.code.TypeTags; 36 import com.sun.tools.javac.tree.JCTree; 37 import com.sun.tools.javac.util.Context; 38 import javax.lang.model.element.*; 39 import javax.lang.model.type.*; 40 41 import static javax.lang.model.element.ElementKind.*; 42 43 46 public class ElementsService { 47 private com.sun.tools.javac.code.Types jctypes; 48 private ASTService model; 49 private Name.Table names; 50 private Types types; 51 private MethodCharacterization mcCache; 52 private VariableCharacterization vcCache; 53 private Element vcKey; 54 private Tree vcTree; 55 private Trees trees; 56 57 private static final Context.Key<ElementsService> KEY = 58 new Context.Key<ElementsService>(); 59 60 public static ElementsService instance(Context context) { 61 ElementsService instance = context.get(KEY); 62 if (instance == null) 63 instance = new ElementsService(context); 64 return instance; 65 } 66 67 protected ElementsService(Context context) { 68 context.put(KEY, this); 69 jctypes = com.sun.tools.javac.code.Types.instance(context); 70 model = ASTService.instance(context); 71 names = Name.Table.instance(context); 72 types = TypesService.instance(context); 73 trees = JavacTrees.instance(context); 74 } 75 76 79 public TypeElement enclosingTypeElement(Element element) { 80 if (element instanceof PackageElement) 81 throw new IllegalArgumentException ("package elements cannot be enclosed"); 82 Element e = element; 83 while (e != null && 84 e.getKind() != CLASS && 85 e.getKind() != INTERFACE && 86 e.getKind() != ANNOTATION_TYPE && 87 e.getKind() != ENUM) { 88 e = e.getEnclosingElement(); 89 } 90 return (TypeElement)e; 91 } 92 93 96 public TypeElement outermostTypeElement(Element element) { 97 Element e = element; 98 Element prev = null; 99 while (e.getKind() != PACKAGE) { 100 prev = e; 101 e = e.getEnclosingElement(); 102 } 103 return (TypeElement)prev; 104 } 105 106 109 public PackageElement packageElement(Element element) { 110 Element e = element; 111 while (e.getKind() != PACKAGE) { 112 e = e.getEnclosingElement(); 113 } 114 return (PackageElement)e; 115 } 116 117 121 public boolean overridesMethod(ExecutableElement element) { 122 MethodSymbol m = (MethodSymbol)element; 123 if ((m.flags() & Flags.STATIC) == 0) { 124 ClassSymbol owner = (ClassSymbol) m.owner; 125 for (Type sup = jctypes.supertype(m.owner.type); 126 sup.tag == TypeTags.CLASS; 127 sup = jctypes.supertype(sup)) { 128 for (Scope.Entry e = sup.tsym.members().lookup(m.name); 129 e.scope != null; e = e.next()) { 130 if (m.overrides(e.sym, owner, jctypes, true)) 131 return true; 132 } 133 } 134 } 135 return false; 136 } 137 138 142 public boolean implementsMethod(ExecutableElement element) { 143 MethodSymbol m = (MethodSymbol)element; 144 TypeSymbol owner = (TypeSymbol) m.owner; 145 for (Type type : jctypes.interfaces(m.owner.type)) { 146 for (Scope.Entry e = type.tsym.members().lookup(m.name); 147 e.scope != null; e = e.next()) { 148 if (m.overrides(e.sym, owner, jctypes, true)) 149 return true; 150 } 151 } 152 return false; 153 } 154 155 public boolean isOverridden(Element s) { 156 return getMethodCharacterization().isOverridden(s); 157 } 158 159 public boolean overrides(ExecutableElement s) { 160 return getMethodCharacterization().overrides(s); 161 } 162 163 public boolean referenced(Element e, Element parent) { 164 return getCharacterization(parent).referenced(e); 165 } 166 167 public boolean assigned(Element e, Element parent) { 168 return getCharacterization(parent).assigned(e); 169 } 170 171 private MethodCharacterization getMethodCharacterization() { 172 if (mcCache == null) { 173 mcCache = new MethodCharacterization(jctypes, (JCTree)model.getRoot()); 174 } 175 return mcCache; 176 } 177 178 VariableCharacterization getCharacterization(Element s) { 179 if(s!=vcKey|| vcCache==null) { 180 vcTree = trees.getTree(s); 181 vcCache = new VariableCharacterization(vcTree, model, this); 182 vcKey= s; 183 } 184 return vcCache; 185 } 186 187 VariableCharacterization getCharacterization(Tree t) { 188 if(t!=vcTree|| vcCache==null) { 189 vcCache = new VariableCharacterization(t, model, this); 190 vcTree = t; 191 vcKey = null; 192 } 193 return vcCache; 194 } 195 196 public boolean parameter(Element e, Element parent) { 197 return getCharacterization(parent).parameter(e); 198 } 199 200 public boolean alreadyDefinedIn(CharSequence name, ExecutableType method, TypeElement enclClass) { 201 Type.MethodType meth = ((Type)method).asMethodType(); 202 ClassSymbol clazz = (ClassSymbol)enclClass; 203 Scope scope = clazz.members(); 204 Name n = names.fromString(name.toString()); 205 scanSymbol: 206 for(Scope.Entry e = scope.lookup(n); e.scope==scope; e = e.next()) 207 if(e.sym.type instanceof ExecutableType && 208 types.isSubsignature(meth, (ExecutableType)e.sym.type)) 209 return true; 210 return false; 211 } 212 213 public boolean isMemberOf(Element e, TypeElement type) { 214 return ((Symbol)e).isMemberOf((TypeSymbol)type, jctypes); 215 } 216 217 public boolean isDeprecated(Element element) { 218 Symbol sym = (Symbol)element; 219 if ((sym.flags() & Flags.DEPRECATED) != 0 && 220 (sym.owner.flags() & Flags.DEPRECATED) == 0) 221 return true; 222 223 TypeSymbol owner = sym.enclClass(); 225 for (Type sup = jctypes.supertype(owner.type); 226 sup.tag == TypeTags.CLASS; 227 sup = jctypes.supertype(sup)) { 228 for (Scope.Entry e = sup.tsym.members().lookup(sym.name); 229 e.scope != null; e = e.next()) { 230 if (sym.overrides(e.sym, owner, jctypes, true) && 231 (e.sym.flags() & Flags.DEPRECATED) != 0) 232 return true; 233 } 234 } 235 return false; 236 } 237 238 public boolean isLocal(Element element) { 239 return ((Symbol)element).isLocal(); 240 } 241 242 public int getInstanceReferenceCount(Tree t) { 243 return getCharacterization(t).getThisUseCount(); 244 } 245 246 public CharSequence getFullName(Element element) { 247 Symbol sym = (Symbol)element; 248 return element instanceof Symbol.ClassSymbol ? 249 ((Symbol.ClassSymbol)element).fullname : 250 Symbol.TypeSymbol.formFullName(sym.name, sym.owner); 251 } 252 253 public Element getImplementationOf(ExecutableElement method, TypeElement origin) { 254 return ((MethodSymbol)method).implementation((TypeSymbol)origin, jctypes, true); 255 } 256 257 public boolean isSynthetic(Element e) { 258 return (((Symbol) e).flags() & Flags.SYNTHETIC) != 0 || (((Symbol) e).flags() & Flags.GENERATEDCONSTR) != 0; 259 } 260 261 public ExecutableElement getOverriddenMethod(ExecutableElement method) { 262 MethodSymbol m = (MethodSymbol)method; 263 ClassSymbol origin = (ClassSymbol)m.owner; 264 for (Type t = jctypes.supertype(origin.type); t.tag == TypeTags.CLASS; t = jctypes.supertype(t)) { 265 TypeSymbol c = t.tsym; 266 Scope.Entry e = c.members().lookup(m.name); 267 while (e.scope != null) { 268 if (m.overrides(e.sym, origin, jctypes, false)) 269 return (MethodSymbol)e.sym; 270 e = e.next(); 271 } 272 } 273 return null; 274 } 275 } 276 | Popular Tags |