| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.ui.text.correction; |
| |
| import java.lang.reflect.Modifier; |
| import java.util.List; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.Expression; |
| import org.eclipse.jdt.core.dom.IBinding; |
| import org.eclipse.jdt.core.dom.ITypeBinding; |
| import org.eclipse.jdt.core.dom.IVariableBinding; |
| import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; |
| import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; |
| import org.eclipse.jdt.core.dom.rewrite.ListRewrite; |
| |
| import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; |
| import org.eclipse.jdt.internal.corext.dom.ASTNodes; |
| import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; |
| |
| import org.eclipse.jdt.internal.ui.JavaPluginImages; |
| |
| public class AddArgumentCorrectionProposal extends LinkedCorrectionProposal { |
| |
| private int[] fInsertIndexes; |
| private ITypeBinding[] fParamTypes; |
| private ASTNode fCallerNode; |
| |
| public AddArgumentCorrectionProposal(String label, ICompilationUnit cu, ASTNode callerNode, int[] insertIdx, ITypeBinding[] expectedTypes, int relevance) { |
| super(label, cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE)); |
| fCallerNode= callerNode; |
| fInsertIndexes= insertIdx; |
| fParamTypes= expectedTypes; |
| } |
| |
| /*(non-Javadoc) |
| * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite() |
| */ |
| protected ASTRewrite getRewrite() { |
| AST ast= fCallerNode.getAST(); |
| ASTRewrite rewrite= ASTRewrite.create(ast); |
| ChildListPropertyDescriptor property= getProperty(); |
| |
| for (int i= 0; i < fInsertIndexes.length; i++) { |
| int idx= fInsertIndexes[i]; |
| String key= "newarg_" + i; //$NON-NLS-1$ |
| Expression newArg= evaluateArgumentExpressions(ast, fParamTypes[idx], key); |
| ListRewrite listRewriter= rewrite.getListRewrite(fCallerNode, property); |
| listRewriter.insertAt(newArg, idx, null); |
| |
| addLinkedPosition(rewrite.track(newArg), i == 0, key); |
| } |
| return rewrite; |
| } |
| |
| private ChildListPropertyDescriptor getProperty() { |
| List list= fCallerNode.structuralPropertiesForType(); |
| for (int i= 0; i < list.size(); i++) { |
| StructuralPropertyDescriptor curr= (StructuralPropertyDescriptor) list.get(i); |
| if (curr.isChildListProperty() && "arguments".equals(curr.getId())) { //$NON-NLS-1$ |
| return (ChildListPropertyDescriptor) curr; |
| } |
| } |
| return null; |
| |
| } |
| |
| |
| private Expression evaluateArgumentExpressions(AST ast, ITypeBinding requiredType, String key) { |
| CompilationUnit root= (CompilationUnit) fCallerNode.getRoot(); |
| |
| int offset= fCallerNode.getStartPosition(); |
| Expression best= null; |
| ITypeBinding bestType= null; |
| |
| ScopeAnalyzer analyzer= new ScopeAnalyzer(root); |
| IBinding[] bindings= analyzer.getDeclarationsInScope(offset, ScopeAnalyzer.VARIABLES); |
| for (int i= 0; i < bindings.length; i++) { |
| IVariableBinding curr= (IVariableBinding) bindings[i]; |
| ITypeBinding type= curr.getType(); |
| if (type != null && canAssign(type, requiredType) && testModifier(curr)) { |
| if (best == null || isMoreSpecific(bestType, type)) { |
| best= ast.newSimpleName(curr.getName()); |
| bestType= type; |
| } |
| addLinkedPositionProposal(key, curr.getName(), null); |
| } |
| } |
| Expression defaultExpression= ASTNodeFactory.newDefaultExpression(ast, requiredType); |
| if (best == null) { |
| best= defaultExpression; |
| } |
| addLinkedPositionProposal(key, ASTNodes.asString(defaultExpression), null); |
| return best; |
| } |
| |
| private boolean isMoreSpecific(ITypeBinding best, ITypeBinding curr) { |
| return (canAssign(best, curr) && !canAssign(curr, best)); |
| } |
| |
| |
| private boolean canAssign(ITypeBinding curr, ITypeBinding best) { |
| return curr.isAssignmentCompatible(best); |
| } |
| |
| private boolean testModifier(IVariableBinding curr) { |
| int modifiers= curr.getModifiers(); |
| int staticFinal= Modifier.STATIC | Modifier.FINAL; |
| if ((modifiers & staticFinal) == staticFinal) { |
| return false; |
| } |
| if (Modifier.isStatic(modifiers) && !ASTResolving.isInStaticContext(fCallerNode)) { |
| return false; |
| } |
| return true; |
| } |
| } |