1 11 12 package org.eclipse.jdt.internal.ui.text.correction; 13 14 import org.eclipse.core.runtime.CoreException; 15 16 import org.eclipse.jdt.core.ICompilationUnit; 17 18 import org.eclipse.jdt.core.dom.AST; 19 import org.eclipse.jdt.core.dom.ASTNode; 20 import org.eclipse.jdt.core.dom.CastExpression; 21 import org.eclipse.jdt.core.dom.CompilationUnit; 22 import org.eclipse.jdt.core.dom.Expression; 23 import org.eclipse.jdt.core.dom.FieldAccess; 24 import org.eclipse.jdt.core.dom.IBinding; 25 import org.eclipse.jdt.core.dom.ITypeBinding; 26 import org.eclipse.jdt.core.dom.MethodInvocation; 27 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 28 import org.eclipse.jdt.core.dom.QualifiedName; 29 import org.eclipse.jdt.core.dom.Type; 30 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 31 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 32 33 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 34 import org.eclipse.jdt.internal.ui.JavaPluginImages; 35 36 public class CastCompletionProposal extends LinkedCorrectionProposal { 37 38 public static final String ADD_CAST_ID= "org.eclipse.jdt.ui.correction.addCast"; 40 private Expression fNodeToCast; 41 private final Object fCastType; 43 public CastCompletionProposal(String label, ICompilationUnit targetCU, Expression nodeToCast, String castType, int relevance) { 44 super(label, targetCU, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CAST)); 45 fNodeToCast= nodeToCast; 46 fCastType= castType; 47 setCommandId(ADD_CAST_ID); 48 } 49 50 public CastCompletionProposal(String label, ICompilationUnit targetCU, Expression nodeToCast, ITypeBinding castType, int relevance) { 51 super(label, targetCU, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CAST)); 52 fNodeToCast= nodeToCast; 53 fCastType= castType; 54 setCommandId(ADD_CAST_ID); 55 } 56 57 private Type getNewCastTypeNode(ASTRewrite rewrite, ImportRewrite importRewrite) throws CoreException { 58 AST ast= rewrite.getAST(); 59 if (fCastType != null) { 60 if (fCastType instanceof ITypeBinding) { 61 return importRewrite.addImport((ITypeBinding) fCastType, ast); 62 } else { 63 String string= importRewrite.addImport((String ) fCastType); 64 return ASTNodeFactory.newType(ast, string); 65 } 66 } 67 68 ASTNode node= fNodeToCast; 69 ASTNode parent= node.getParent(); 70 if (parent instanceof CastExpression) { 71 node= parent; 72 parent= parent.getParent(); 73 } 74 while (parent instanceof ParenthesizedExpression) { 75 node= parent; 76 parent= parent.getParent(); 77 } 78 if (parent instanceof MethodInvocation) { 79 MethodInvocation invocation= (MethodInvocation) node.getParent(); 80 if (invocation.getExpression() == node) { 81 IBinding targetContext= ASTResolving.getParentMethodOrTypeBinding(node); 82 ITypeBinding[] bindings= ASTResolving.getQualifierGuess(node.getRoot(), invocation.getName().getIdentifier(), invocation.arguments(), targetContext); 83 if (bindings.length > 0) { 84 ITypeBinding first= getCastFavorite(bindings, fNodeToCast.resolveTypeBinding()); 85 86 Type newTypeNode= importRewrite.addImport(first, ast); 87 addLinkedPosition(rewrite.track(newTypeNode), true, "casttype"); for (int i= 0; i < bindings.length; i++) { 89 addLinkedPositionProposal("casttype", bindings[i]); } 91 return newTypeNode; 92 } 93 } 94 } 95 Type newCastType= ast.newSimpleType(ast.newSimpleName("Object")); addLinkedPosition(rewrite.track(newCastType), true, "casttype"); return newCastType; 98 } 99 100 private ITypeBinding getCastFavorite(ITypeBinding[] suggestedCasts, ITypeBinding nodeToCastBinding) { 101 if (nodeToCastBinding == null) { 102 return suggestedCasts[0]; 103 } 104 ITypeBinding favourite= suggestedCasts[0]; 105 for (int i = 0; i < suggestedCasts.length; i++) { 106 ITypeBinding curr= suggestedCasts[i]; 107 if (nodeToCastBinding.isCastCompatible(curr)) { 108 return curr; 109 } 110 if (curr.isInterface()) { 111 favourite= curr; 112 } 113 } 114 return favourite; 115 } 116 117 118 protected ASTRewrite getRewrite() throws CoreException { 119 AST ast= fNodeToCast.getAST(); 120 ASTRewrite rewrite= ASTRewrite.create(ast); 121 ImportRewrite importRewrite= createImportRewrite((CompilationUnit) fNodeToCast.getRoot()); 122 123 Type newTypeNode= getNewCastTypeNode(rewrite, importRewrite); 124 125 if (fNodeToCast.getNodeType() == ASTNode.CAST_EXPRESSION) { 126 CastExpression expression= (CastExpression) fNodeToCast; 127 rewrite.replace(expression.getType(), newTypeNode, null); 128 } else { 129 Expression expressionCopy= (Expression) rewrite.createCopyTarget(fNodeToCast); 130 if (needsInnerParantheses(fNodeToCast)) { 131 ParenthesizedExpression parenthesizedExpression= ast.newParenthesizedExpression(); 132 parenthesizedExpression.setExpression(expressionCopy); 133 expressionCopy= parenthesizedExpression; 134 } 135 136 CastExpression castExpression= ast.newCastExpression(); 137 castExpression.setExpression(expressionCopy); 138 castExpression.setType(newTypeNode); 139 140 ASTNode replacingNode= castExpression; 141 if (needsOuterParantheses(fNodeToCast)) { 142 ParenthesizedExpression parenthesizedExpression= ast.newParenthesizedExpression(); 143 parenthesizedExpression.setExpression(castExpression); 144 replacingNode= parenthesizedExpression; 145 } 146 147 rewrite.replace(fNodeToCast, replacingNode, null); 148 } 149 return rewrite; 150 } 151 152 private static boolean needsInnerParantheses(ASTNode nodeToCast) { 153 int nodeType= nodeToCast.getNodeType(); 154 155 return nodeType == ASTNode.INFIX_EXPRESSION || nodeType == ASTNode.CONDITIONAL_EXPRESSION 157 || nodeType == ASTNode.ASSIGNMENT || nodeType == ASTNode.INSTANCEOF_EXPRESSION; 158 } 159 160 private static boolean needsOuterParantheses(ASTNode nodeToCast) { 161 ASTNode parent= nodeToCast.getParent(); 162 if (parent instanceof MethodInvocation) { 163 if (((MethodInvocation)parent).getExpression() == nodeToCast) { 164 return true; 165 } 166 } else if (parent instanceof QualifiedName) { 167 if (((QualifiedName)parent).getQualifier() == nodeToCast) { 168 return true; 169 } 170 } else if (parent instanceof FieldAccess) { 171 if (((FieldAccess)parent).getExpression() == nodeToCast) { 172 return true; 173 } 174 } 175 return false; 176 } 177 178 179 } 180 | Popular Tags |