1 11 package org.eclipse.jdt.internal.corext.codemanipulation; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.eclipse.core.runtime.Assert; 21 import org.eclipse.core.runtime.CoreException; 22 23 import org.eclipse.jdt.core.Flags; 24 import org.eclipse.jdt.core.ICompilationUnit; 25 import org.eclipse.jdt.core.JavaCore; 26 import org.eclipse.jdt.core.NamingConventions; 27 import org.eclipse.jdt.core.dom.AST; 28 import org.eclipse.jdt.core.dom.ASTNode; 29 import org.eclipse.jdt.core.dom.Annotation; 30 import org.eclipse.jdt.core.dom.Assignment; 31 import org.eclipse.jdt.core.dom.Block; 32 import org.eclipse.jdt.core.dom.Expression; 33 import org.eclipse.jdt.core.dom.FieldAccess; 34 import org.eclipse.jdt.core.dom.IBinding; 35 import org.eclipse.jdt.core.dom.IMethodBinding; 36 import org.eclipse.jdt.core.dom.IPackageBinding; 37 import org.eclipse.jdt.core.dom.ITypeBinding; 38 import org.eclipse.jdt.core.dom.IVariableBinding; 39 import org.eclipse.jdt.core.dom.Javadoc; 40 import org.eclipse.jdt.core.dom.MethodDeclaration; 41 import org.eclipse.jdt.core.dom.MethodInvocation; 42 import org.eclipse.jdt.core.dom.Modifier; 43 import org.eclipse.jdt.core.dom.ParameterizedType; 44 import org.eclipse.jdt.core.dom.PrimitiveType; 45 import org.eclipse.jdt.core.dom.ReturnStatement; 46 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 47 import org.eclipse.jdt.core.dom.Statement; 48 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 49 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 50 import org.eclipse.jdt.core.dom.Type; 51 import org.eclipse.jdt.core.dom.TypeParameter; 52 import org.eclipse.jdt.core.dom.WildcardType; 53 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 54 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 55 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; 56 57 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 58 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 59 import org.eclipse.jdt.internal.corext.dom.Bindings; 60 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 61 62 import org.eclipse.jdt.ui.CodeGeneration; 63 64 69 public final class StubUtility2 { 70 71 public static void addOverrideAnnotation(ASTRewrite rewrite, MethodDeclaration decl, IMethodBinding binding) { 72 String version= binding.getJavaElement().getJavaProject().getOption(JavaCore.COMPILER_COMPLIANCE, true); 73 if (!binding.getDeclaringClass().isInterface() || !JavaModelUtil.isVersionLessThan(version, JavaCore.VERSION_1_6)) { 74 final Annotation marker= rewrite.getAST().newMarkerAnnotation(); 75 marker.setTypeName(rewrite.getAST().newSimpleName("Override")); rewrite.getListRewrite(decl, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(marker, null); 77 } 78 } 79 80 public static MethodDeclaration createConstructorStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, IMethodBinding binding, String type, int modifiers, boolean omitSuperForDefConst, boolean todo, CodeGenerationSettings settings) throws CoreException { 81 AST ast= rewrite.getAST(); 82 MethodDeclaration decl= ast.newMethodDeclaration(); 83 decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifiers & ~Modifier.ABSTRACT & ~Modifier.NATIVE)); 84 decl.setName(ast.newSimpleName(type)); 85 decl.setConstructor(true); 86 87 ITypeBinding[] typeParams= binding.getTypeParameters(); 88 List typeParameters= decl.typeParameters(); 89 for (int i= 0; i < typeParams.length; i++) { 90 ITypeBinding curr= typeParams[i]; 91 TypeParameter newTypeParam= ast.newTypeParameter(); 92 newTypeParam.setName(ast.newSimpleName(curr.getName())); 93 ITypeBinding[] typeBounds= curr.getTypeBounds(); 94 if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) { List newTypeBounds= newTypeParam.typeBounds(); 96 for (int k= 0; k < typeBounds.length; k++) { 97 newTypeBounds.add(imports.addImport(typeBounds[k], ast)); 98 } 99 } 100 typeParameters.add(newTypeParam); 101 } 102 103 List parameters= createParameters(unit, imports, ast, binding, decl, null); 104 105 List thrownExceptions= decl.thrownExceptions(); 106 ITypeBinding[] excTypes= binding.getExceptionTypes(); 107 for (int i= 0; i < excTypes.length; i++) { 108 String excTypeName= imports.addImport(excTypes[i]); 109 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName)); 110 } 111 112 Block body= ast.newBlock(); 113 decl.setBody(body); 114 115 String delimiter= StubUtility.getLineDelimiterUsed(unit); 116 String bodyStatement= ""; if (!omitSuperForDefConst || !parameters.isEmpty()) { 118 SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation(); 119 SingleVariableDeclaration varDecl= null; 120 for (Iterator iterator= parameters.iterator(); iterator.hasNext();) { 121 varDecl= (SingleVariableDeclaration) iterator.next(); 122 invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier())); 123 } 124 bodyStatement= ASTNodes.asFormattedString(invocation, 0, delimiter, unit.getJavaProject().getOptions(true)); 125 } 126 127 if (todo) { 128 String placeHolder= CodeGeneration.getMethodBodyContent(unit, type, binding.getName(), true, bodyStatement, delimiter); 129 if (placeHolder != null) { 130 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT); 131 body.statements().add(todoNode); 132 } 133 } else { 134 ASTNode statementNode= rewrite.createStringPlaceholder(bodyStatement, ASTNode.RETURN_STATEMENT); 135 body.statements().add(statementNode); 136 } 137 138 if (settings != null && settings.createComments) { 139 String string= CodeGeneration.getMethodComment(unit, type, decl, binding, delimiter); 140 if (string != null) { 141 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 142 decl.setJavadoc(javadoc); 143 } 144 } 145 return decl; 146 } 147 148 public static MethodDeclaration createConstructorStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, ITypeBinding typeBinding, AST ast, IMethodBinding superConstructor, IVariableBinding[] variableBindings, int modifiers, CodeGenerationSettings settings) throws CoreException { 149 150 MethodDeclaration decl= ast.newMethodDeclaration(); 151 decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifiers & ~Modifier.ABSTRACT & ~Modifier.NATIVE)); 152 decl.setName(ast.newSimpleName(typeBinding.getName())); 153 decl.setConstructor(true); 154 155 List parameters= decl.parameters(); 156 if (superConstructor != null) { 157 ITypeBinding[] typeParams= superConstructor.getTypeParameters(); 158 List typeParameters= decl.typeParameters(); 159 for (int i= 0; i < typeParams.length; i++) { 160 ITypeBinding curr= typeParams[i]; 161 TypeParameter newTypeParam= ast.newTypeParameter(); 162 newTypeParam.setName(ast.newSimpleName(curr.getName())); 163 ITypeBinding[] typeBounds= curr.getTypeBounds(); 164 if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) { List newTypeBounds= newTypeParam.typeBounds(); 166 for (int k= 0; k < typeBounds.length; k++) { 167 newTypeBounds.add(imports.addImport(typeBounds[k], ast)); 168 } 169 } 170 typeParameters.add(newTypeParam); 171 } 172 173 createParameters(unit, imports, ast, superConstructor, decl, null); 174 175 List thrownExceptions= decl.thrownExceptions(); 176 ITypeBinding[] excTypes= superConstructor.getExceptionTypes(); 177 for (int i= 0; i < excTypes.length; i++) { 178 String excTypeName= imports.addImport(excTypes[i]); 179 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName)); 180 } 181 } 182 183 Block body= ast.newBlock(); 184 decl.setBody(body); 185 186 String delimiter= StubUtility.getLineDelimiterUsed(unit); 187 188 if (superConstructor != null) { 189 SuperConstructorInvocation invocation= ast.newSuperConstructorInvocation(); 190 SingleVariableDeclaration varDecl= null; 191 for (Iterator iterator= parameters.iterator(); iterator.hasNext();) { 192 varDecl= (SingleVariableDeclaration) iterator.next(); 193 invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier())); 194 } 195 body.statements().add(invocation); 196 } 197 198 List prohibited= new ArrayList (); 199 for (final Iterator iterator= parameters.iterator(); iterator.hasNext();) 200 prohibited.add(((SingleVariableDeclaration) iterator.next()).getName().getIdentifier()); 201 String param= null; 202 List list= new ArrayList (prohibited); 203 String [] excluded= null; 204 for (int i= 0; i < variableBindings.length; i++) { 205 SingleVariableDeclaration var= ast.newSingleVariableDeclaration(); 206 var.setType(imports.addImport(variableBindings[i].getType(), ast)); 207 excluded= new String [list.size()]; 208 list.toArray(excluded); 209 param= getParameterName(unit, variableBindings[i], excluded); 210 list.add(param); 211 var.setName(ast.newSimpleName(param)); 212 parameters.add(var); 213 } 214 215 list= new ArrayList (prohibited); 216 for (int i= 0; i < variableBindings.length; i++) { 217 excluded= new String [list.size()]; 218 list.toArray(excluded); 219 final String paramName= getParameterName(unit, variableBindings[i], excluded); 220 list.add(paramName); 221 final String fieldName= variableBindings[i].getName(); 222 Expression expression= null; 223 if (paramName.equals(fieldName) || settings.useKeywordThis) { 224 FieldAccess access= ast.newFieldAccess(); 225 access.setExpression(ast.newThisExpression()); 226 access.setName(ast.newSimpleName(fieldName)); 227 expression= access; 228 } else 229 expression= ast.newSimpleName(fieldName); 230 Assignment assignment= ast.newAssignment(); 231 assignment.setLeftHandSide(expression); 232 assignment.setRightHandSide(ast.newSimpleName(paramName)); 233 assignment.setOperator(Assignment.Operator.ASSIGN); 234 body.statements().add(ast.newExpressionStatement(assignment)); 235 } 236 237 if (settings != null && settings.createComments) { 238 String string= CodeGeneration.getMethodComment(unit, typeBinding.getName(), decl, superConstructor, delimiter); 239 if (string != null) { 240 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 241 decl.setJavadoc(javadoc); 242 } 243 } 244 return decl; 245 } 246 247 public static MethodDeclaration createDelegationStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, AST ast, IBinding[] bindings, CodeGenerationSettings settings) throws CoreException { 248 Assert.isNotNull(bindings); 249 Assert.isNotNull(settings); 250 Assert.isTrue(bindings.length == 2); 251 Assert.isTrue(bindings[0] instanceof IVariableBinding); 252 Assert.isTrue(bindings[1] instanceof IMethodBinding); 253 254 IVariableBinding variableBinding= (IVariableBinding) bindings[0]; 255 IMethodBinding methodBinding= (IMethodBinding) bindings[1]; 256 257 MethodDeclaration decl= ast.newMethodDeclaration(); 258 decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, methodBinding.getModifiers() & ~Modifier.SYNCHRONIZED & ~Modifier.ABSTRACT & ~Modifier.NATIVE)); 259 260 decl.setName(ast.newSimpleName(methodBinding.getName())); 261 decl.setConstructor(false); 262 263 ITypeBinding[] typeParams= methodBinding.getTypeParameters(); 264 List typeParameters= decl.typeParameters(); 265 for (int i= 0; i < typeParams.length; i++) { 266 ITypeBinding curr= typeParams[i]; 267 TypeParameter newTypeParam= ast.newTypeParameter(); 268 newTypeParam.setName(ast.newSimpleName(curr.getName())); 269 ITypeBinding[] typeBounds= curr.getTypeBounds(); 270 if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) { List newTypeBounds= newTypeParam.typeBounds(); 272 for (int k= 0; k < typeBounds.length; k++) { 273 newTypeBounds.add(imports.addImport(typeBounds[k], ast)); 274 } 275 } 276 typeParameters.add(newTypeParam); 277 } 278 279 decl.setReturnType2(imports.addImport(methodBinding.getReturnType(), ast)); 280 281 List parameters= decl.parameters(); 282 ITypeBinding[] params= methodBinding.getParameterTypes(); 283 String [] paramNames= StubUtility.suggestArgumentNames(unit.getJavaProject(), methodBinding); 284 for (int i= 0; i < params.length; i++) { 285 SingleVariableDeclaration varDecl= ast.newSingleVariableDeclaration(); 286 if (params[i].isWildcardType() && !params[i].isUpperbound()) 287 varDecl.setType(imports.addImport(params[i].getBound(), ast)); 288 else { 289 if (methodBinding.isVarargs() && params[i].isArray() && i == params.length - 1) { 290 StringBuffer buffer= new StringBuffer (imports.addImport(params[i].getElementType())); 291 for (int dim= 1; dim < params[i].getDimensions(); dim++) 292 buffer.append("[]"); varDecl.setType(ASTNodeFactory.newType(ast, buffer.toString())); 294 varDecl.setVarargs(true); 295 } else 296 varDecl.setType(imports.addImport(params[i], ast)); 297 } 298 varDecl.setName(ast.newSimpleName(paramNames[i])); 299 parameters.add(varDecl); 300 } 301 302 List thrownExceptions= decl.thrownExceptions(); 303 ITypeBinding[] excTypes= methodBinding.getExceptionTypes(); 304 for (int i= 0; i < excTypes.length; i++) { 305 String excTypeName= imports.addImport(excTypes[i]); 306 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName)); 307 } 308 309 Block body= ast.newBlock(); 310 decl.setBody(body); 311 312 String delimiter= StubUtility.getLineDelimiterUsed(unit); 313 314 Statement statement= null; 315 MethodInvocation invocation= ast.newMethodInvocation(); 316 invocation.setName(ast.newSimpleName(methodBinding.getName())); 317 List arguments= invocation.arguments(); 318 for (int i= 0; i < params.length; i++) 319 arguments.add(ast.newSimpleName(paramNames[i])); 320 if (settings.useKeywordThis) { 321 FieldAccess access= ast.newFieldAccess(); 322 access.setExpression(ast.newThisExpression()); 323 access.setName(ast.newSimpleName(variableBinding.getName())); 324 invocation.setExpression(access); 325 } else 326 invocation.setExpression(ast.newSimpleName(variableBinding.getName())); 327 if (methodBinding.getReturnType().isPrimitive() && methodBinding.getReturnType().getName().equals("void")) { statement= ast.newExpressionStatement(invocation); 329 } else { 330 ReturnStatement returnStatement= ast.newReturnStatement(); 331 returnStatement.setExpression(invocation); 332 statement= returnStatement; 333 } 334 body.statements().add(statement); 335 336 ITypeBinding declaringType= variableBinding.getDeclaringClass(); 337 if (declaringType == null) { return decl; 339 } 340 341 String qualifiedName= declaringType.getQualifiedName(); 342 IPackageBinding packageBinding= declaringType.getPackage(); 343 if (packageBinding != null) { 344 if (packageBinding.getName().length() > 0 && qualifiedName.startsWith(packageBinding.getName())) 345 qualifiedName= qualifiedName.substring(packageBinding.getName().length()); 346 } 347 348 if (settings.createComments) { 349 354 methodBinding= methodBinding.getMethodDeclaration(); 355 String declaringClassQualifiedName= methodBinding.getDeclaringClass().getQualifiedName(); 356 String linkToMethodName= methodBinding.getName(); 357 String [] parameterTypesQualifiedNames= StubUtility.getParameterTypeNamesForSeeTag(methodBinding); 358 String string= StubUtility.getMethodComment(unit, qualifiedName, decl, methodBinding.isDeprecated(), linkToMethodName, declaringClassQualifiedName, parameterTypesQualifiedNames, true, delimiter); 359 if (string != null) { 360 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 361 decl.setJavadoc(javadoc); 362 } 363 } 364 return decl; 365 } 366 367 public static MethodDeclaration createImplementationStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite imports, AST ast, IMethodBinding binding, String type, CodeGenerationSettings settings, boolean deferred, ImportRewriteContext context) throws CoreException { 368 369 MethodDeclaration decl= ast.newMethodDeclaration(); 370 decl.modifiers().addAll(getImplementationModifiers(ast, binding, deferred)); 371 372 decl.setName(ast.newSimpleName(binding.getName())); 373 decl.setConstructor(false); 374 375 ITypeBinding[] typeParams= binding.getTypeParameters(); 376 List typeParameters= decl.typeParameters(); 377 for (int i= 0; i < typeParams.length; i++) { 378 ITypeBinding curr= typeParams[i]; 379 TypeParameter newTypeParam= ast.newTypeParameter(); 380 newTypeParam.setName(ast.newSimpleName(curr.getName())); 381 ITypeBinding[] typeBounds= curr.getTypeBounds(); 382 if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) { List newTypeBounds= newTypeParam.typeBounds(); 384 for (int k= 0; k < typeBounds.length; k++) { 385 newTypeBounds.add(imports.addImport(typeBounds[k], ast, context)); 386 } 387 } 388 typeParameters.add(newTypeParam); 389 } 390 391 decl.setReturnType2(imports.addImport(binding.getReturnType(), ast, context)); 392 393 List parameters= createParameters(unit, imports, ast, binding, decl, context); 394 395 List thrownExceptions= decl.thrownExceptions(); 396 ITypeBinding[] excTypes= binding.getExceptionTypes(); 397 for (int i= 0; i < excTypes.length; i++) { 398 String excTypeName= imports.addImport(excTypes[i], context); 399 thrownExceptions.add(ASTNodeFactory.newName(ast, excTypeName)); 400 } 401 402 String delimiter= StubUtility.getLineDelimiterUsed(unit); 403 if (!deferred) { 404 Map options= unit.getJavaProject().getOptions(true); 405 406 Block body= ast.newBlock(); 407 decl.setBody(body); 408 409 String bodyStatement= ""; ITypeBinding declaringType= binding.getDeclaringClass(); 411 if (Modifier.isAbstract(binding.getModifiers()) || declaringType.isAnnotation() || declaringType.isInterface()) { 412 Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions()); 413 if (expression != null) { 414 ReturnStatement returnStatement= ast.newReturnStatement(); 415 returnStatement.setExpression(expression); 416 bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options); 417 } 418 } else { 419 SuperMethodInvocation invocation= ast.newSuperMethodInvocation(); 420 invocation.setName(ast.newSimpleName(binding.getName())); 421 SingleVariableDeclaration varDecl= null; 422 for (Iterator iterator= parameters.iterator(); iterator.hasNext();) { 423 varDecl= (SingleVariableDeclaration) iterator.next(); 424 invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier())); 425 } 426 Expression expression= invocation; 427 Type returnType= decl.getReturnType2(); 428 if (returnType != null && (returnType instanceof PrimitiveType) && ((PrimitiveType) returnType).getPrimitiveTypeCode().equals(PrimitiveType.VOID)) { 429 bodyStatement= ASTNodes.asFormattedString(ast.newExpressionStatement(expression), 0, delimiter, options); 430 } else { 431 ReturnStatement returnStatement= ast.newReturnStatement(); 432 returnStatement.setExpression(expression); 433 bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options); 434 } 435 } 436 437 String placeHolder= CodeGeneration.getMethodBodyContent(unit, type, binding.getName(), false, bodyStatement, delimiter); 438 if (placeHolder != null) { 439 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT); 440 body.statements().add(todoNode); 441 } 442 } 443 444 if (settings.createComments) { 445 String string= CodeGeneration.getMethodComment(unit, type, decl, binding, delimiter); 446 if (string != null) { 447 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 448 decl.setJavadoc(javadoc); 449 } 450 } 451 if (settings.overrideAnnotation && JavaModelUtil.is50OrHigher(unit.getJavaProject())) { 452 addOverrideAnnotation(rewrite, decl, binding); 453 } 454 455 return decl; 456 } 457 458 public static MethodDeclaration createImplementationStub(ICompilationUnit unit, ASTRewrite rewrite, ImportRewrite importRewrite, IMethodBinding binding, String type, boolean deferred, CodeGenerationSettings settings) throws CoreException { 459 AST ast= rewrite.getAST(); 460 MethodDeclaration decl= ast.newMethodDeclaration(); 461 decl.modifiers().addAll(getImplementationModifiers(ast, binding, deferred)); 462 463 decl.setName(ast.newSimpleName(binding.getName())); 464 decl.setConstructor(false); 465 466 ITypeBinding[] typeParams= binding.getTypeParameters(); 467 List typeParameters= decl.typeParameters(); 468 for (int index= 0; index < typeParams.length; index++) { 469 ITypeBinding curr= typeParams[index]; 470 TypeParameter newTypeParam= ast.newTypeParameter(); 471 newTypeParam.setName(ast.newSimpleName(curr.getName())); 472 ITypeBinding[] typeBounds= curr.getTypeBounds(); 473 if (typeBounds.length != 1 || !"java.lang.Object".equals(typeBounds[0].getQualifiedName())) { List newTypeBounds= newTypeParam.typeBounds(); 475 for (int offset= 0; offset < typeBounds.length; offset++) { 476 newTypeBounds.add(createTypeNode(importRewrite, typeBounds[offset], ast)); 477 } 478 } 479 typeParameters.add(newTypeParam); 480 } 481 482 decl.setReturnType2(createTypeNode(importRewrite, binding.getReturnType(), ast)); 483 484 List parameters= createParameters(unit, importRewrite, ast, binding, decl); 485 486 List thrownExceptions= decl.thrownExceptions(); 487 ITypeBinding[] excTypes= binding.getExceptionTypes(); 488 for (int index= 0; index < excTypes.length; index++) 489 thrownExceptions.add(ASTNodeFactory.newName(ast, importRewrite != null ? importRewrite.addImport(excTypes[index]) : excTypes[index].getQualifiedName())); 490 491 String delimiter= StubUtility.getLineDelimiterUsed(unit); 492 if (!deferred) { 493 Map options= unit.getJavaProject().getOptions(true); 494 495 Block body= ast.newBlock(); 496 decl.setBody(body); 497 498 String bodyStatement= ""; ITypeBinding declaringType= binding.getDeclaringClass(); 500 if (Modifier.isAbstract(binding.getModifiers()) || declaringType.isAnnotation() || declaringType.isInterface()) { 501 Expression expression= ASTNodeFactory.newDefaultExpression(ast, decl.getReturnType2(), decl.getExtraDimensions()); 502 if (expression != null) { 503 ReturnStatement returnStatement= ast.newReturnStatement(); 504 returnStatement.setExpression(expression); 505 bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options); 506 } 507 } else { 508 SuperMethodInvocation invocation= ast.newSuperMethodInvocation(); 509 invocation.setName(ast.newSimpleName(binding.getName())); 510 SingleVariableDeclaration varDecl= null; 511 for (Iterator iterator= parameters.iterator(); iterator.hasNext();) { 512 varDecl= (SingleVariableDeclaration) iterator.next(); 513 invocation.arguments().add(ast.newSimpleName(varDecl.getName().getIdentifier())); 514 } 515 Expression expression= invocation; 516 Type returnType= decl.getReturnType2(); 517 if (returnType instanceof PrimitiveType && ((PrimitiveType) returnType).getPrimitiveTypeCode().equals(PrimitiveType.VOID)) { 518 bodyStatement= ASTNodes.asFormattedString(ast.newExpressionStatement(expression), 0, delimiter, options); 519 } else { 520 ReturnStatement returnStatement= ast.newReturnStatement(); 521 returnStatement.setExpression(expression); 522 bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, options); 523 } 524 } 525 526 String placeHolder= CodeGeneration.getMethodBodyContent(unit, type, binding.getName(), false, bodyStatement, delimiter); 527 if (placeHolder != null) { 528 ASTNode todoNode= rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT); 529 body.statements().add(todoNode); 530 } 531 } 532 533 if (settings != null && settings.createComments) { 534 String string= CodeGeneration.getMethodComment(unit, type, decl, binding, delimiter); 535 if (string != null) { 536 Javadoc javadoc= (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC); 537 decl.setJavadoc(javadoc); 538 } 539 } 540 if (settings != null && settings.overrideAnnotation && JavaModelUtil.is50OrHigher(unit.getJavaProject())) { 541 addOverrideAnnotation(rewrite, decl, binding); 542 } 543 return decl; 544 } 545 546 private static List createParameters(ICompilationUnit unit, ImportRewrite imports, AST ast, IMethodBinding binding, MethodDeclaration decl, ImportRewriteContext context) { 547 List parameters= decl.parameters(); 548 ITypeBinding[] params= binding.getParameterTypes(); 549 String [] paramNames= StubUtility.suggestArgumentNames(unit.getJavaProject(), binding); 550 for (int i= 0; i < params.length; i++) { 551 SingleVariableDeclaration var= ast.newSingleVariableDeclaration(); 552 if (binding.isVarargs() && params[i].isArray() && i == params.length - 1) { 553 StringBuffer buffer= new StringBuffer (imports.addImport(params[i].getElementType(), context)); 554 for (int dim= 1; dim < params[i].getDimensions(); dim++) 555 buffer.append("[]"); var.setType(ASTNodeFactory.newType(ast, buffer.toString())); 557 var.setVarargs(true); 558 } else 559 var.setType(imports.addImport(params[i], ast, context)); 560 var.setName(ast.newSimpleName(paramNames[i])); 561 parameters.add(var); 562 } 563 return parameters; 564 } 565 566 private static List createParameters(ICompilationUnit unit, ImportRewrite imports, AST ast, IMethodBinding binding, MethodDeclaration decl) { 567 List parameters= decl.parameters(); 568 ITypeBinding[] params= binding.getParameterTypes(); 569 String [] paramNames= StubUtility.suggestArgumentNames(unit.getJavaProject(), binding); 570 for (int i= 0; i < params.length; i++) { 571 SingleVariableDeclaration var= ast.newSingleVariableDeclaration(); 572 if (binding.isVarargs() && params[i].isArray() && i == params.length - 1) { 573 final ITypeBinding elementType= params[i].getElementType(); 574 StringBuffer buffer= new StringBuffer (imports != null ? imports.addImport(elementType) : elementType.getQualifiedName()); 575 for (int dim= 1; dim < params[i].getDimensions(); dim++) 576 buffer.append("[]"); var.setType(ASTNodeFactory.newType(ast, buffer.toString())); 578 var.setVarargs(true); 579 } else 580 var.setType(createTypeNode(imports, params[i], ast)); 581 var.setName(ast.newSimpleName(paramNames[i])); 582 parameters.add(var); 583 } 584 return parameters; 585 } 586 587 private static Type createTypeNode(ImportRewrite importRewrite, ITypeBinding binding, AST ast) { 588 if (importRewrite != null) 589 return importRewrite.addImport(binding, ast); 590 return createTypeNode(binding, ast); 591 } 592 593 private static Type createTypeNode(ITypeBinding binding, AST ast) { 594 if (binding.isPrimitive()) 595 return ast.newPrimitiveType(PrimitiveType.toCode(binding.getName())); 596 ITypeBinding normalized= Bindings.normalizeTypeBinding(binding); 597 if (normalized == null) 598 return ast.newSimpleType(ast.newSimpleName("invalid")); else if (normalized.isTypeVariable()) 600 return ast.newSimpleType(ast.newSimpleName(binding.getName())); 601 else if (normalized.isWildcardType()) { 602 WildcardType type= ast.newWildcardType(); 603 ITypeBinding bound= normalized.getBound(); 604 if (bound != null) 605 type.setBound(createTypeNode(bound, ast), normalized.isUpperbound()); 606 return type; 607 } else if (normalized.isArray()) 608 return ast.newArrayType(createTypeNode(normalized.getElementType(), ast), normalized.getDimensions()); 609 String qualified= Bindings.getRawQualifiedName(normalized); 610 if (qualified.length() > 0) { 611 ITypeBinding[] typeArguments= normalized.getTypeArguments(); 612 if (typeArguments.length > 0) { 613 ParameterizedType type= ast.newParameterizedType(ast.newSimpleType(ASTNodeFactory.newName(ast, qualified))); 614 List arguments= type.typeArguments(); 615 for (int index= 0; index < typeArguments.length; index++) 616 arguments.add(createTypeNode(typeArguments[index], ast)); 617 return type; 618 } 619 return ast.newSimpleType(ASTNodeFactory.newName(ast, qualified)); 620 } 621 return ast.newSimpleType(ASTNodeFactory.newName(ast, Bindings.getRawName(normalized))); 622 } 623 624 private static IMethodBinding findMethodBinding(IMethodBinding method, List allMethods) { 625 for (int i= 0; i < allMethods.size(); i++) { 626 IMethodBinding curr= (IMethodBinding) allMethods.get(i); 627 if (Bindings.isSubsignature(method, curr)) { 628 return curr; 629 } 630 } 631 return null; 632 } 633 634 private static IMethodBinding findOverridingMethod(IMethodBinding method, List allMethods) { 635 for (int i= 0; i < allMethods.size(); i++) { 636 IMethodBinding curr= (IMethodBinding) allMethods.get(i); 637 if (Bindings.areOverriddenMethods(curr, method) || Bindings.isSubsignature(curr, method)) 638 return curr; 639 } 640 return null; 641 } 642 643 private static void findUnimplementedInterfaceMethods(ITypeBinding typeBinding, HashSet visited, ArrayList allMethods, IPackageBinding currPack, ArrayList toImplement) { 644 if (visited.add(typeBinding)) { 645 IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods(); 646 for (int i= 0; i < typeMethods.length; i++) { 647 IMethodBinding curr= typeMethods[i]; 648 IMethodBinding impl= findMethodBinding(curr, allMethods); 649 if (impl == null || !Bindings.isVisibleInHierarchy(impl, currPack)) { 650 if (impl != null) 651 allMethods.remove(impl); 652 toImplement.add(curr); 653 allMethods.add(curr); 654 } 655 } 656 ITypeBinding[] superInterfaces= typeBinding.getInterfaces(); 657 for (int i= 0; i < superInterfaces.length; i++) 658 findUnimplementedInterfaceMethods(superInterfaces[i], visited, allMethods, currPack, toImplement); 659 } 660 } 661 662 public static IBinding[][] getDelegatableMethods(AST ast, ITypeBinding binding) { 663 final List tuples= new ArrayList (); 664 final List declared= new ArrayList (); 665 IMethodBinding[] typeMethods= binding.getDeclaredMethods(); 666 for (int index= 0; index < typeMethods.length; index++) 667 declared.add(typeMethods[index]); 668 IVariableBinding[] typeFields= binding.getDeclaredFields(); 669 for (int index= 0; index < typeFields.length; index++) { 670 IVariableBinding fieldBinding= typeFields[index]; 671 if (fieldBinding.isField() && !fieldBinding.isEnumConstant() && !fieldBinding.isSynthetic()) 672 getDelegatableMethods(ast, tuples, new ArrayList (declared), fieldBinding, fieldBinding.getType(), binding); 673 } 674 return (IBinding[][]) tuples.toArray(new IBinding[tuples.size()][2]); 676 } 677 678 private static void getDelegatableMethods(AST ast, List tuples, List methods, IVariableBinding fieldBinding, ITypeBinding typeBinding, ITypeBinding binding) { 679 boolean match= false; 680 if (typeBinding.isTypeVariable()) { 681 ITypeBinding[] typeBounds= typeBinding.getTypeBounds(); 682 if (typeBounds == null || typeBounds.length == 0) 683 typeBounds= new ITypeBinding[] { ast.resolveWellKnownType("java.lang.Object") }; for (int index= 0; index < typeBounds.length; index++) { 685 IMethodBinding[] candidates= getDelegateCandidates(typeBounds[index], binding); 686 for (int candidate= 0; candidate < candidates.length; candidate++) { 687 match= false; 688 final IMethodBinding methodBinding= candidates[candidate]; 689 for (int offset= 0; offset < methods.size() && !match; offset++) { 690 if (Bindings.areOverriddenMethods((IMethodBinding) methods.get(offset), methodBinding)) 691 match= true; 692 } 693 if (!match) { 694 tuples.add(new IBinding[] { fieldBinding, methodBinding }); 695 methods.add(methodBinding); 696 } 697 } 698 final ITypeBinding superclass= typeBounds[index].getSuperclass(); 699 if (superclass != null) 700 getDelegatableMethods(ast, tuples, methods, fieldBinding, superclass, binding); 701 ITypeBinding[] superInterfaces= typeBounds[index].getInterfaces(); 702 for (int offset= 0; offset < superInterfaces.length; offset++) 703 getDelegatableMethods(ast, tuples, methods, fieldBinding, superInterfaces[offset], binding); 704 } 705 } else { 706 IMethodBinding[] candidates= getDelegateCandidates(typeBinding, binding); 707 for (int index= 0; index < candidates.length; index++) { 708 match= false; 709 final IMethodBinding methodBinding= candidates[index]; 710 for (int offset= 0; offset < methods.size() && !match; offset++) { 711 if (Bindings.areOverriddenMethods((IMethodBinding) methods.get(offset), methodBinding)) 712 match= true; 713 } 714 if (!match) { 715 tuples.add(new IBinding[] { fieldBinding, methodBinding }); 716 methods.add(methodBinding); 717 } 718 } 719 final ITypeBinding superclass= typeBinding.getSuperclass(); 720 if (superclass != null) 721 getDelegatableMethods(ast, tuples, methods, fieldBinding, superclass, binding); 722 ITypeBinding[] superInterfaces= typeBinding.getInterfaces(); 723 for (int offset= 0; offset < superInterfaces.length; offset++) 724 getDelegatableMethods(ast, tuples, methods, fieldBinding, superInterfaces[offset], binding); 725 } 726 } 727 728 private static IMethodBinding[] getDelegateCandidates(ITypeBinding binding, ITypeBinding hierarchy) { 729 List allMethods= new ArrayList (); 730 boolean isInterface= binding.isInterface(); 731 IMethodBinding[] typeMethods= binding.getDeclaredMethods(); 732 for (int index= 0; index < typeMethods.length; index++) { 733 final int modifiers= typeMethods[index].getModifiers(); 734 if (!typeMethods[index].isConstructor() && !Modifier.isStatic(modifiers) && (isInterface || Modifier.isPublic(modifiers))) { 735 IMethodBinding result= Bindings.findOverriddenMethodInHierarchy(hierarchy, typeMethods[index]); 736 if (result != null && Flags.isFinal(result.getModifiers())) 737 continue; 738 ITypeBinding[] parameterBindings= typeMethods[index].getParameterTypes(); 739 boolean upper= false; 740 for (int offset= 0; offset < parameterBindings.length; offset++) { 741 if (parameterBindings[offset].isWildcardType() && parameterBindings[offset].isUpperbound()) 742 upper= true; 743 } 744 if (!upper) 745 allMethods.add(typeMethods[index]); 746 } 747 } 748 return (IMethodBinding[]) allMethods.toArray(new IMethodBinding[allMethods.size()]); 749 } 750 751 private static List getImplementationModifiers(AST ast, IMethodBinding method, boolean deferred) { 752 int modifiers= method.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE & ~Modifier.PRIVATE; 753 if (deferred) { 754 modifiers= modifiers & ~Modifier.PROTECTED; 755 modifiers= modifiers | Modifier.PUBLIC; 756 } 757 return ASTNodeFactory.newModifiers(ast, modifiers); 758 } 759 760 public static IMethodBinding[] getOverridableMethods(AST ast, ITypeBinding typeBinding, boolean isSubType) { 761 List allMethods= new ArrayList (); 762 IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods(); 763 for (int index= 0; index < typeMethods.length; index++) { 764 final int modifiers= typeMethods[index].getModifiers(); 765 if (!typeMethods[index].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) 766 allMethods.add(typeMethods[index]); 767 } 768 ITypeBinding clazz= typeBinding.getSuperclass(); 769 while (clazz != null) { 770 IMethodBinding[] methods= clazz.getDeclaredMethods(); 771 for (int offset= 0; offset < methods.length; offset++) { 772 final int modifiers= methods[offset].getModifiers(); 773 if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { 774 if (findOverridingMethod(methods[offset], allMethods) == null) 775 allMethods.add(methods[offset]); 776 } 777 } 778 clazz= clazz.getSuperclass(); 779 } 780 clazz= typeBinding; 781 while (clazz != null) { 782 ITypeBinding[] superInterfaces= clazz.getInterfaces(); 783 for (int index= 0; index < superInterfaces.length; index++) { 784 getOverridableMethods(ast, superInterfaces[index], allMethods); 785 } 786 clazz= clazz.getSuperclass(); 787 } 788 if (typeBinding.isInterface()) 789 getOverridableMethods(ast, ast.resolveWellKnownType("java.lang.Object"), allMethods); if (!isSubType) 791 allMethods.removeAll(Arrays.asList(typeMethods)); 792 int modifiers= 0; 793 if (!typeBinding.isInterface()) { 794 for (int index= allMethods.size() - 1; index >= 0; index--) { 795 IMethodBinding method= (IMethodBinding) allMethods.get(index); 796 modifiers= method.getModifiers(); 797 if (Modifier.isFinal(modifiers)) 798 allMethods.remove(index); 799 } 800 } 801 return (IMethodBinding[]) allMethods.toArray(new IMethodBinding[allMethods.size()]); 802 } 803 804 private static void getOverridableMethods(AST ast, ITypeBinding superBinding, List allMethods) { 805 IMethodBinding[] methods= superBinding.getDeclaredMethods(); 806 for (int offset= 0; offset < methods.length; offset++) { 807 final int modifiers= methods[offset].getModifiers(); 808 if (!methods[offset].isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { 809 if (findOverridingMethod(methods[offset], allMethods) == null && !Modifier.isStatic(modifiers)) 810 allMethods.add(methods[offset]); 811 } 812 } 813 ITypeBinding[] superInterfaces= superBinding.getInterfaces(); 814 for (int index= 0; index < superInterfaces.length; index++) { 815 getOverridableMethods(ast, superInterfaces[index], allMethods); 816 } 817 } 818 819 private static String getParameterName(ICompilationUnit unit, IVariableBinding binding, String [] excluded) { 820 final String name= NamingConventions.removePrefixAndSuffixForFieldName(unit.getJavaProject(), binding.getName(), binding.getModifiers()); 821 return StubUtility.suggestArgumentName(unit.getJavaProject(), name, excluded); 822 } 823 824 public static IMethodBinding[] getUnimplementedMethods(ITypeBinding typeBinding) { 825 ArrayList allMethods= new ArrayList (); 826 ArrayList toImplement= new ArrayList (); 827 828 IMethodBinding[] typeMethods= typeBinding.getDeclaredMethods(); 829 for (int i= 0; i < typeMethods.length; i++) { 830 IMethodBinding curr= typeMethods[i]; 831 int modifiers= curr.getModifiers(); 832 if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { 833 allMethods.add(curr); 834 } 835 } 836 837 ITypeBinding superClass= typeBinding.getSuperclass(); 838 while (superClass != null) { 839 typeMethods= superClass.getDeclaredMethods(); 840 for (int i= 0; i < typeMethods.length; i++) { 841 IMethodBinding curr= typeMethods[i]; 842 int modifiers= curr.getModifiers(); 843 if (!curr.isConstructor() && !Modifier.isStatic(modifiers) && !Modifier.isPrivate(modifiers)) { 844 if (findMethodBinding(curr, allMethods) == null) { 845 allMethods.add(curr); 846 } 847 } 848 } 849 superClass= superClass.getSuperclass(); 850 } 851 852 for (int i= 0; i < allMethods.size(); i++) { 853 IMethodBinding curr= (IMethodBinding) allMethods.get(i); 854 int modifiers= curr.getModifiers(); 855 if ((Modifier.isAbstract(modifiers) || curr.getDeclaringClass().isInterface()) && (typeBinding != curr.getDeclaringClass())) { 856 toImplement.add(curr); 858 } 859 } 860 861 HashSet visited= new HashSet (); 862 ITypeBinding curr= typeBinding; 863 while (curr != null) { 864 ITypeBinding[] superInterfaces= curr.getInterfaces(); 865 for (int i= 0; i < superInterfaces.length; i++) { 866 findUnimplementedInterfaceMethods(superInterfaces[i], visited, allMethods, typeBinding.getPackage(), toImplement); 867 } 868 curr= curr.getSuperclass(); 869 } 870 871 return (IMethodBinding[]) toImplement.toArray(new IMethodBinding[toImplement.size()]); 872 } 873 874 public static IMethodBinding[] getVisibleConstructors(ITypeBinding binding, boolean accountExisting, boolean proposeDefault) { 875 List constructorMethods= new ArrayList (); 876 List existingConstructors= null; 877 ITypeBinding superType= binding.getSuperclass(); 878 if (superType == null) 879 return new IMethodBinding[0]; 880 if (accountExisting) { 881 IMethodBinding[] methods= binding.getDeclaredMethods(); 882 existingConstructors= new ArrayList (methods.length); 883 for (int index= 0; index < methods.length; index++) { 884 IMethodBinding method= methods[index]; 885 if (method.isConstructor() && !method.isDefaultConstructor()) 886 existingConstructors.add(method); 887 } 888 } 889 if (existingConstructors != null) 890 constructorMethods.addAll(existingConstructors); 891 IMethodBinding[] methods= binding.getDeclaredMethods(); 892 IMethodBinding[] superMethods= superType.getDeclaredMethods(); 893 for (int index= 0; index < superMethods.length; index++) { 894 IMethodBinding method= superMethods[index]; 895 if (method.isConstructor()) { 896 if (Bindings.isVisibleInHierarchy(method, binding.getPackage()) && (!accountExisting || !Bindings.containsSignatureEquivalentConstructor(methods, method))) 897 constructorMethods.add(method); 898 } 899 } 900 if (existingConstructors != null) 901 constructorMethods.removeAll(existingConstructors); 902 if (constructorMethods.isEmpty()) { 903 superType= binding; 904 while (superType.getSuperclass() != null) 905 superType= superType.getSuperclass(); 906 IMethodBinding method= Bindings.findMethodInType(superType, "Object", new ITypeBinding[0]); if (method != null) { 908 if ((proposeDefault || (!accountExisting || (existingConstructors == null || existingConstructors.isEmpty()))) && (!accountExisting || !Bindings.containsSignatureEquivalentConstructor(methods, method))) 909 constructorMethods.add(method); 910 } 911 } 912 return (IMethodBinding[]) constructorMethods.toArray(new IMethodBinding[constructorMethods.size()]); 913 } 914 915 916 917 920 private StubUtility2() { 921 } 923 } 924 | Popular Tags |