1 11 package org.eclipse.jdt.internal.corext.refactoring.binary; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.core.runtime.Assert; 17 import org.eclipse.core.runtime.IProgressMonitor; 18 import org.eclipse.core.runtime.NullProgressMonitor; 19 import org.eclipse.core.runtime.SubProgressMonitor; 20 21 import org.eclipse.jdt.core.Flags; 22 import org.eclipse.jdt.core.IField; 23 import org.eclipse.jdt.core.IJavaElement; 24 import org.eclipse.jdt.core.IMember; 25 import org.eclipse.jdt.core.IMethod; 26 import org.eclipse.jdt.core.IType; 27 import org.eclipse.jdt.core.ITypeParameter; 28 import org.eclipse.jdt.core.JavaModelException; 29 import org.eclipse.jdt.core.Signature; 30 31 import org.eclipse.jdt.internal.corext.refactoring.Checks; 32 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 33 34 public class StubCreator { 35 36 37 protected StringBuffer fBuffer; 38 39 40 protected final boolean fStubInvisible; 41 42 public StubCreator(final boolean stubInvisible) { 43 fStubInvisible= stubInvisible; 44 } 45 46 protected void appendEnumConstants(final IType type) throws JavaModelException { 47 final IField[] fields= type.getFields(); 48 final List list= new ArrayList (fields.length); 49 for (int index= 0; index < fields.length; index++) { 50 final IField field= fields[index]; 51 if (Flags.isEnum(field.getFlags())) 52 list.add(field); 53 } 54 for (int index= 0; index < list.size(); index++) { 55 if (index > 0) 56 fBuffer.append(","); fBuffer.append(((IField) list.get(index)).getElementName()); 58 } 59 fBuffer.append(";"); } 61 62 protected void appendExpression(final String signature) { 63 switch (signature.charAt(0)) { 64 case Signature.C_BOOLEAN: 65 fBuffer.append("false"); break; 67 case Signature.C_BYTE: 68 case Signature.C_CHAR: 69 case Signature.C_DOUBLE: 70 case Signature.C_FLOAT: 71 case Signature.C_INT: 72 case Signature.C_LONG: 73 case Signature.C_SHORT: 74 fBuffer.append("0"); break; 76 default: 77 fBuffer.append("("); fBuffer.append(Signature.toString(signature)); 79 fBuffer.append(")"); fBuffer.append("null"); break; 82 } 83 } 84 85 protected void appendFieldDeclaration(final IField field) throws JavaModelException { 86 appendFlags(field); 87 fBuffer.append(" "); final String signature= field.getTypeSignature(); 89 fBuffer.append(Signature.toString(signature)); 90 fBuffer.append(" "); fBuffer.append(field.getElementName()); 92 if (Flags.isFinal(field.getFlags())) { 93 fBuffer.append("="); appendExpression(signature); 95 } 96 fBuffer.append(";"); } 98 99 protected void appendFlags(final IMember member) throws JavaModelException { 100 int flags= member.getFlags(); 101 final int kind= member.getElementType(); 102 if (kind == IJavaElement.TYPE) { 103 flags&= ~Flags.AccSuper; 104 final IType type= (IType) member; 105 if (!type.isMember()) 106 flags&= ~Flags.AccPrivate; 107 } 108 if (Flags.isEnum(flags)) 109 flags&= ~Flags.AccFinal; 110 if (kind == IJavaElement.METHOD) { 111 flags&= ~Flags.AccVarargs; 112 flags&= ~Flags.AccBridge; 113 } 114 if (flags != 0) 115 fBuffer.append(Flags.toString(flags)); 116 } 117 118 protected void appendMembers(final IType type, final IProgressMonitor monitor) throws JavaModelException { 119 try { 120 monitor.beginTask(RefactoringCoreMessages.StubCreationOperation_creating_type_stubs, 1); 121 final IJavaElement[] children= type.getChildren(); 122 for (int index= 0; index < children.length; index++) { 123 final IMember child= (IMember) children[index]; 124 final int flags= child.getFlags(); 125 final boolean isPrivate= Flags.isPrivate(flags); 126 final boolean isDefault= !Flags.isPublic(flags) && !Flags.isProtected(flags) && !isPrivate; 127 final boolean stub= fStubInvisible || (!isPrivate && !isDefault); 128 if (child instanceof IType) { 129 if (stub) 130 appendTypeDeclaration((IType) child, new SubProgressMonitor(monitor, 1)); 131 } else if (child instanceof IField) { 132 if (stub && !Flags.isEnum(flags) && !Flags.isSynthetic(flags)) 133 appendFieldDeclaration((IField) child); 134 } else if (child instanceof IMethod) { 135 final IMethod method= (IMethod) child; 136 final String name= method.getElementName(); 137 if (method.getDeclaringType().isEnum()) { 138 final int count= method.getNumberOfParameters(); 139 if (count == 0 && "values".equals(name)) continue; 141 if (count == 1 && "valueOf".equals(name) && "Ljava.lang.String;".equals(method.getParameterTypes()[0])) continue; 143 if (method.isConstructor()) 144 continue; 145 } 146 boolean skip= !stub || name.equals("<clinit>"); if (method.isConstructor()) 148 skip= false; 149 skip= skip || Flags.isSynthetic(flags) || Flags.isBridge(flags); 150 if (!skip) 151 appendMethodDeclaration(method); 152 } 153 fBuffer.append("\n"); } 155 } finally { 156 monitor.done(); 157 } 158 } 159 160 protected void appendMethodBody(final IMethod method) throws JavaModelException { 161 if (method.isConstructor()) { 162 final IType declaringType= method.getDeclaringType(); 163 String superSignature= declaringType.getSuperclassTypeSignature(); 164 if (superSignature != null) { 165 superSignature= Signature.getTypeErasure(superSignature); 166 final IType superclass= declaringType.getJavaProject().findType(Signature.getSignatureQualifier(superSignature), Signature.getSignatureSimpleName(superSignature)); 167 if (superclass != null) { 168 final IMethod[] superMethods= superclass.getMethods(); 169 IMethod superConstructor= null; 170 final int length= superMethods.length; 171 for (int index= 0; index < length; index++) { 172 final IMethod superMethod= superMethods[index]; 173 if (superMethod.isConstructor() && !Flags.isPrivate(superMethod.getFlags())) { 174 superConstructor= superMethod; 175 if (superConstructor.getExceptionTypes().length == 0) 176 break; 177 } 178 } 179 if (superConstructor != null) { 180 final String [] superParameters= superConstructor.getParameterTypes(); 181 final int paramLength= superParameters.length; 182 if (paramLength != 0) { 183 fBuffer.append("super("); for (int index= 0; index < paramLength; index++) { 185 if (index > 0) 186 fBuffer.append(","); appendExpression(superParameters[index]); 188 } 189 fBuffer.append(");"); } 191 } 192 } 193 } 194 } else { 195 String returnType= method.getReturnType(); 196 if (!Signature.SIG_VOID.equals(returnType)) { 197 fBuffer.append("return "); appendExpression(returnType); 199 fBuffer.append(";"); } 201 } 202 } 203 204 protected void appendMethodDeclaration(final IMethod method) throws JavaModelException { 205 appendFlags(method); 206 fBuffer.append(" "); final String returnType= method.getReturnType(); 208 if (!method.isConstructor()) { 209 fBuffer.append(Signature.toString(returnType)); 210 fBuffer.append(" "); final ITypeParameter[] parameters= method.getTypeParameters(); 212 if (parameters.length > 0) { 213 appendTypeParameters(parameters); 214 fBuffer.append(" "); } 216 } 217 fBuffer.append(method.getElementName()); 218 fBuffer.append("("); final String [] parameterTypes= method.getParameterTypes(); 220 final int flags= method.getFlags(); 221 final boolean varargs= Flags.isVarargs(flags); 222 final int parameterLength= parameterTypes.length; 223 for (int index= 0; index < parameterLength; index++) { 224 if (index > 0) 225 fBuffer.append(","); fBuffer.append(Signature.toString(parameterTypes[index])); 227 if (varargs && index == parameterLength - 1) { 228 final int length= fBuffer.length(); 229 if (length >= 2 && fBuffer.indexOf("[]", length - 2) >= 0) fBuffer.setLength(length - 2); 231 fBuffer.append("..."); } 233 fBuffer.append(" "); appendMethodParameterName(method, index); 235 } 236 fBuffer.append(")"); final String [] exceptionTypes= method.getExceptionTypes(); 238 final int exceptionLength= exceptionTypes.length; 239 if (exceptionLength > 0) 240 fBuffer.append(" throws "); for (int index= 0; index < exceptionLength; index++) { 242 if (index > 0) 243 fBuffer.append(","); fBuffer.append(Signature.toString(exceptionTypes[index])); 245 } 246 if (Flags.isAbstract(flags) || Flags.isNative(flags)) 247 fBuffer.append(";"); else { 249 fBuffer.append("{\n"); appendMethodBody(method); 251 fBuffer.append("}"); } 253 } 254 255 protected void appendMethodParameterName(IMethod method, int index) { 256 fBuffer.append("a"); fBuffer.append(index); 258 } 259 260 protected void appendSuperInterfaceTypes(final IType type) throws JavaModelException { 261 final String [] signatures= type.getSuperInterfaceTypeSignatures(); 262 if (signatures.length > 0) { 263 if (type.isInterface()) 264 fBuffer.append(" extends "); else 266 fBuffer.append(" implements "); } 268 for (int index= 0; index < signatures.length; index++) { 269 if (index > 0) 270 fBuffer.append(","); fBuffer.append(Signature.toString(signatures[index])); 272 } 273 } 274 275 protected void appendTopLevelType(final IType type, IProgressMonitor subProgressMonitor) throws JavaModelException { 276 String packageName= type.getPackageFragment().getElementName(); 277 if (packageName.length() > 0) { 278 fBuffer.append("package "); fBuffer.append(packageName); 280 fBuffer.append(";\n"); } 282 appendTypeDeclaration(type, subProgressMonitor); 283 } 284 285 protected void appendTypeDeclaration(final IType type, final IProgressMonitor monitor) throws JavaModelException { 286 try { 287 monitor.beginTask(RefactoringCoreMessages.StubCreationOperation_creating_type_stubs, 1); 288 if (type.isInterface()) { 289 appendFlags(type); 290 fBuffer.append(" interface "); fBuffer.append(type.getElementName()); 292 appendTypeParameters(type.getTypeParameters()); 293 appendSuperInterfaceTypes(type); 294 fBuffer.append("{\n"); appendMembers(type, new SubProgressMonitor(monitor, 1)); 296 fBuffer.append("}"); } else if (type.isClass()) { 298 appendFlags(type); 299 fBuffer.append(" class "); fBuffer.append(type.getElementName()); 301 appendTypeParameters(type.getTypeParameters()); 302 final String signature= type.getSuperclassTypeSignature(); 303 if (signature != null) { 304 fBuffer.append(" extends "); fBuffer.append(Signature.toString(signature)); 306 } 307 appendSuperInterfaceTypes(type); 308 fBuffer.append("{\n"); appendMembers(type, new SubProgressMonitor(monitor, 1)); 310 fBuffer.append("}"); } else if (type.isAnnotation()) { 312 appendFlags(type); 313 fBuffer.append(" @interface "); fBuffer.append(type.getElementName()); 315 fBuffer.append("{\n"); appendMembers(type, new SubProgressMonitor(monitor, 1)); 317 fBuffer.append("}"); } else if (type.isEnum()) { 319 appendFlags(type); 320 fBuffer.append(" enum "); fBuffer.append(type.getElementName()); 322 appendSuperInterfaceTypes(type); 323 fBuffer.append("{\n"); appendEnumConstants(type); 325 appendMembers(type, new SubProgressMonitor(monitor, 1)); 326 fBuffer.append("}"); } 328 } finally { 329 monitor.done(); 330 } 331 } 332 333 protected void appendTypeParameters(final ITypeParameter[] parameters) throws JavaModelException { 334 final int length= parameters.length; 335 if (length > 0) 336 fBuffer.append("<"); for (int index= 0; index < length; index++) { 338 if (index > 0) 339 fBuffer.append(","); final ITypeParameter parameter= parameters[index]; 341 fBuffer.append(parameter.getElementName()); 342 final String [] bounds= parameter.getBounds(); 343 final int size= bounds.length; 344 if (size > 0) 345 fBuffer.append(" extends "); for (int offset= 0; offset < size; offset++) { 347 if (offset > 0) 348 fBuffer.append(" & "); fBuffer.append(bounds[offset]); 350 } 351 } 352 if (length > 0) 353 fBuffer.append(">"); } 355 356 363 public String createStub(IType topLevelType, IProgressMonitor monitor) throws JavaModelException { 364 Assert.isTrue(Checks.isTopLevel(topLevelType)); 365 if (monitor == null) 366 monitor= new NullProgressMonitor(); 367 368 fBuffer= new StringBuffer (2046); 369 appendTopLevelType(topLevelType, monitor); 370 String result= fBuffer.toString(); 371 fBuffer= null; 372 return result; 373 } 374 375 } 376 | Popular Tags |