1 19 20 21 package org.netbeans.modules.javacore.internalapi; 22 23 import java.util.*; 24 import org.netbeans.jmi.javamodel.*; 25 import org.netbeans.modules.javacore.api.JavaModel; 26 import org.netbeans.modules.javacore.jmiimpl.javamodel.ArrayCloneMethod; 27 import org.netbeans.modules.javacore.jmiimpl.javamodel.JavaClassImpl; 28 import org.netbeans.modules.javacore.jmiimpl.javamodel.MetadataElement; 29 import org.netbeans.modules.javacore.jmiimpl.javamodel.MethodImpl; 30 import org.netbeans.modules.javacore.jmiimpl.javamodel.ParameterizedTypeImpl; 31 import org.netbeans.modules.javacore.jmiimpl.javamodel.SemiPersistentElement; 32 import org.netbeans.modules.javacore.parser.Scope; 33 import org.netbeans.modules.javacore.parser.TypeRef; 34 35 39 public class JavaModelUtil { 40 41 private JavaModelUtil() { 42 } 43 44 49 public static Set getExceptionsFromStatements(List statements) { 50 return computeAllExceptions(statements, new HashSet()); 51 } 52 53 private static Set computeAllExceptions(List elements,Set ignoredExceptions) { 54 Iterator elIt=elements.iterator(); 55 Set foundExceptions=new HashSet(); 56 57 while(elIt.hasNext()) { 58 Object el=elIt.next(); 59 60 if (el instanceof Invocation) { 61 Invocation inv=(Invocation)el; 62 CallableFeature cf=(CallableFeature)inv.getElement(); 63 64 if (cf!=null) { 65 List exceptions=cf.getExceptions(); 66 67 if (!exceptions.isEmpty()) { 68 Iterator exIt=exceptions.iterator(); 69 70 while(exIt.hasNext()) { 71 addException((JavaClass)exIt.next(), foundExceptions, ignoredExceptions); 72 } 73 } 74 } 75 } else if (el instanceof MultipartId) { 76 continue; 77 } else if (el instanceof ThrowStatement) { 78 ThrowStatement throwSt=(ThrowStatement)el; 79 Expression ex=throwSt.getExpression(); 80 81 if (ex!=null) addException((JavaClass)ex.getType(), foundExceptions, ignoredExceptions); 82 } else if (el instanceof TryStatement) { 83 TryStatement trySt=(TryStatement)el; 84 StatementBlock body=trySt.getBody(); 85 86 if (body!=null) { 87 List catches=trySt.getCatches(); 88 Iterator catchIt=catches.iterator(); 89 Set localIgnores=new HashSet(ignoredExceptions); 90 StatementBlock finalizer=trySt.getFinalizer(); 91 92 while (catchIt.hasNext()) { 93 Catch c=(Catch)catchIt.next(); 94 JavaClass ex=(JavaClass)c.getParameter().getType(); 95 96 addException(ex, localIgnores, Collections.EMPTY_SET); 97 } 98 foundExceptions.addAll(computeAllExceptions(Collections.singletonList(body), localIgnores)); 99 foundExceptions.addAll(computeAllExceptions(catches, ignoredExceptions)); 100 if (finalizer!=null) 101 foundExceptions.addAll(computeAllExceptions(Collections.singletonList(finalizer), ignoredExceptions)); 102 return foundExceptions; 103 } 104 } 105 foundExceptions.addAll(computeAllExceptions(((Element)el).getChildren(), ignoredExceptions)); 106 } 107 return foundExceptions; 108 } 109 110 private static void addException(final JavaClass ex, final Set foundExceptions, final Set ignoredExceptions) { 111 Iterator jclsIt; 112 JavaClass exc = (JavaClass) unwrapElement(ex); 113 114 if (exc==null || exc instanceof UnresolvedClass) 115 return; 116 if (ignoredExceptions.contains(exc) || foundExceptions.contains(exc)) 117 return; 118 jclsIt=ignoredExceptions.iterator(); 119 while(jclsIt.hasNext()) { 120 JavaClass igEx=(JavaClass)jclsIt.next(); 121 122 if (exc.isSubTypeOf(igEx)) { 123 return; 124 } 125 } 126 jclsIt=foundExceptions.iterator(); 127 while(jclsIt.hasNext()) { 128 JavaClass fex=(JavaClass)jclsIt.next(); 129 130 if (exc.isSubTypeOf(fex)) { 131 return; 132 } 133 } 134 foundExceptions.add(exc); 135 } 136 137 146 public static List getSelectedStatements(Resource rsc,int startOffset,int endOffset) { 147 Element firstStComposite; 148 Element lastStComposite; 149 int lastStEndOffset; 150 List selectedStatements; 151 Statement firstStatement=getStatement(rsc, startOffset); 152 Statement lastStatement=getStatement(rsc, endOffset-1); 153 if (firstStatement==null || lastStatement==null) { 154 return null; } 156 firstStatement=adjustFirstStatement(startOffset,firstStatement); 157 lastStatement=adjustLastStatement(endOffset,lastStatement); 158 if (firstStatement==null || lastStatement==null) { 159 return null; } 161 firstStComposite=(Element)firstStatement.refImmediateComposite(); 162 lastStComposite=(Element)lastStatement.refImmediateComposite(); 163 lastStEndOffset=lastStComposite.getEndOffset(); 164 while (!firstStComposite.equals(lastStComposite)) { 165 if (!(lastStComposite instanceof Statement) || lastStComposite.getEndOffset()!=lastStEndOffset) { 166 return null; } 168 lastStatement=(Statement)lastStComposite; 169 lastStComposite=(Element)lastStatement.refImmediateComposite(); 170 } 171 if (firstStatement.equals(lastStatement)) { 172 selectedStatements=Collections.singletonList(firstStatement); 173 } else { 174 List statements; 175 if (firstStComposite instanceof StatementBlock) { 176 statements = ((StatementBlock)firstStComposite).getStatements(); 177 } else { 178 statements = ((Case)firstStComposite).getStatements(); 179 } 180 int firstIndex=statements.indexOf(firstStatement); 181 Iterator sIt=statements.listIterator(firstIndex); 182 Object st; 183 selectedStatements=new ArrayList(); 184 if (sIt.hasNext()) { 185 do { 186 st=sIt.next(); 187 selectedStatements.add(st); 188 189 } while(!st.equals(lastStatement)); 190 } 191 } 192 return selectedStatements; 193 } 194 195 private static Statement getStatement(Resource rsc,int offset) { 196 Element el=rsc.getElementByOffset(offset); 197 int elStart,elEnd; 198 199 if (el instanceof Feature || el instanceof Resource) 200 return null; 201 elStart=el.getStartOffset(); 202 elEnd=el.getEndOffset(); 203 while(el!=null && !(el instanceof Statement)) { 204 el = (Element)el.refImmediateComposite(); 205 if (el instanceof Feature || (el.getStartOffset()!=elStart && el.getEndOffset()!=elEnd)) 206 return null; 207 } 208 return (Statement)el; 209 } 210 211 private static Statement adjustFirstStatement(int startOffset,Statement s) { 212 JavaMetamodel model=JavaMetamodel.getManager(); 213 Iterator chIt; 214 215 if (model.getElementPosition(s).getBegin().getOffset()==startOffset) 216 return s; 217 chIt=s.getChildren().iterator(); 218 while(chIt.hasNext()) { 219 Element el=(Element)chIt.next(); 220 221 if (el instanceof Statement) { 222 if (model.getElementPosition(el).getBegin().getOffset()>startOffset) { 223 return (Statement)el; 224 } 225 } 226 } 227 return null; 228 } 229 230 private static Statement adjustLastStatement(int endOffset,Statement s) { 231 JavaMetamodel model=JavaMetamodel.getManager(); 232 ListIterator chIt; 233 List children; 234 235 if (model.getElementPosition(s).getEnd().getOffset()==endOffset) 236 return s; 237 children=s.getChildren(); 238 chIt=children.listIterator(children.size()); 239 while(chIt.hasPrevious()) { 240 Element el=(Element)chIt.previous(); 241 242 if (el instanceof Statement) { 243 if (model.getElementPosition(el).getEnd().getOffset()<endOffset) { 244 return (Statement)el; 245 } 246 } 247 } 248 return null; 249 } 250 251 260 public static MultipartId resolveImportsForClass(Element scope,JavaClass jcls) { 261 return (MultipartId)typeToTypeReference(scope,jcls); 262 } 263 264 274 public static TypeReference resolveImportsForType(Element scope,Type type) { 275 return (TypeReference)typeToTypeReference(scope,type); 276 } 277 278 private static Element typeToTypeReference(Element scope,Type type) { 279 JavaModelPackage jpck; 280 MultipartIdClass mpidClass; 281 282 if (type == null) { 283 return null; 284 } 285 scope=unwrapElement(scope); 286 jpck=(JavaModelPackage)scope.refImmediatePackage(); 287 mpidClass=jpck.getMultipartId(); 288 if (type instanceof TypeParameter) { 289 return mpidClass.createMultipartId(type.getName(),null,null); 290 } else if (type instanceof ParameterizedType) { 291 ParameterizedTypeImpl paramType = (ParameterizedTypeImpl) type; 292 Type typePars[] = (Type[])paramType.getParameters().toArray(new Type[0]); 293 TypeArgument args[] = new TypeArgument[typePars.length]; 294 int i = 0; 295 for (; i<typePars.length; i++) { 296 args[i] = (TypeArgument)typeToTypeReference(scope,typePars[i]); 297 int status = paramType.getWildCardStatus(i); 298 if (status != 0) { 299 args[i] = jpck.getWildCard().createWildCard(status == 1, status == 3 ? null : (MultipartId) args[i]); 300 } 301 } 302 MultipartId parentName=(MultipartId) typeToTypeReference(scope,paramType.getDeclaringClass()); 303 JavaClass def=paramType.getDefinition(); 304 String name; 305 306 if (parentName==null) { 307 MultipartId defId=createImportsForClass(scope,def); 308 309 if (typePars.length==0) 310 return defId; 311 name=defId.getName(); 312 } else 313 name=def.getSimpleName(); 314 return mpidClass.createMultipartId(name, parentName, Arrays.asList(args)); 315 } else if (type instanceof Array) { 316 int dimCount = 0; 317 Type currType = type; 318 while (currType instanceof Array) { 319 dimCount++; 320 currType = ((Array) currType).getType(); 321 } 322 return jpck.getArrayReference().createArrayReference(null,(MultipartId)typeToTypeReference(scope,currType), dimCount); 323 } else if (type instanceof JavaClass) { 324 if (type instanceof JavaClassImpl && ((JavaClassImpl)type).isTransient()) return mpidClass.createMultipartId(type.getName(),null,null); 326 return createImportsForClass(scope,(JavaClass)type); 327 } else if (type instanceof PrimitiveType) { 328 return mpidClass.createMultipartId(type.getName(),null,null); 329 } 330 throw new IllegalArgumentException ("Unable to convert to typeref: " + type.getClass().getName()); } 332 333 private static MultipartId createImportsForClass(Element scope,JavaClass type) { 334 JavaModelPackage jpck=(JavaModelPackage)scope.refImmediatePackage(); 335 MultipartIdClass mpidClass=jpck.getMultipartId(); 336 337 if (type instanceof UnresolvedClass) { 338 return mpidClass.createMultipartId(type.getName(),null,null); 339 } else { 340 Scope sc=Scope.computeTypeScope(scope); 341 String simpleName=type.getSimpleName(); 342 Object resolvedClass=sc.lookup(simpleName); 343 Import imp; 344 345 if (resolvedClass!=null) { 346 if (type.getName().equals(resolvedClass)) { return mpidClass.createMultipartId(simpleName,null,null); 348 } 349 return mpidClass.createMultipartId(type.getName(),null,null); 351 } 352 imp=jpck.getImport().createImport(type.getName(),null,false,false); 354 scope.getResource().addImport(imp); 355 return mpidClass.createMultipartId(simpleName,null,null); 356 } 357 } 358 359 366 public static Feature getDeclaringFeature(Element element) { 367 while (!(element instanceof Feature) && element!=null) { 368 element=(Element)element.refImmediateComposite(); 369 } 370 return (Feature)element; 371 } 372 373 383 public static Element duplicateInScope(Element scope,Element original) { 384 scope=unwrapElement(scope); 385 JavaModelPackage pck=(JavaModelPackage)scope.refImmediatePackage(); 386 MetadataElement newElement=(MetadataElement)unwrapElement(original).duplicate(pck); 387 388 newElement.fixImports(scope,original); 389 return newElement; 390 } 391 392 private static MetadataElement unwrapElement(Element el) { 393 if (el instanceof MetadataElement) 394 return (MetadataElement)el; 395 if (el instanceof ParameterizedType) { 396 return (MetadataElement)((ParameterizedType)el).getDefinition(); 397 } 398 if (el instanceof ParameterizedTypeImpl.Wrapper) { 399 return (MetadataElement)((ParameterizedTypeImpl.Wrapper)el).getWrappedObject(); 400 } 401 throw new IllegalArgumentException ("Unknown type "+el.getClass()); 402 } 403 404 409 public static Collection getOverriddenMethods(Method method) { 410 if (method instanceof ArrayCloneMethod) { 411 ArrayList result = new ArrayList(1); 412 result.add( 413 ((JavaClass)JavaModel.getDefaultExtent().getType() 414 .resolve("java.lang.Object")).getMethod("clone",Collections.EMPTY_LIST, false)); return result; 416 } 417 MethodImpl mImpl=(MethodImpl)unwrapElement(method); 418 419 return mImpl.getOverriddenMethods(); 420 } 421 427 public static TypeReference createTypeReferenceFromType(Type type) { 428 JavaModelPackage extent = JavaModel.getDefaultExtent(); 429 TypeRef typeRef = SemiPersistentElement.typeToTypeRef(type); 430 431 return (TypeReference)SemiPersistentElement.typeRefToTypeReference(extent, typeRef, 0); 432 } 433 } 434 | Popular Tags |