/*******************************************************************************
* Copyright (c) 2000, 2011 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
* Sebastian Davids <sdavids@gmx.de> - Bug 37432 getInvertEqualsProposal
* Benjamin Muskalla <b.muskalla@gmx.net> - Bug 36350 convertToStringBufferPropsal
* Chris West (Faux) <eclipse@goeswhere.com> - [quick assist] "Use 'StringBuilder' for string concatenation" could fix existing
* misuses - https://bugs.eclipse.org/bugs/show_bug.cgi?id=282755
*******************************************************************************/
package org.eclipse.che.ide.ext.java.jdt.internal.text.correction;
import org.eclipse.che.ide.ext.java.jdt.Images;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.IProblemLocation;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.JavaCompletionProposal;
import org.eclipse.che.ide.ext.java.jdt.core.IJavaModelMarker;
import org.eclipse.che.ide.ext.java.jdt.core.JavaCore;
import org.eclipse.che.ide.ext.java.jdt.core.NamingConventions;
import org.eclipse.che.ide.ext.java.jdt.core.compiler.IProblem;
import org.eclipse.che.ide.ext.java.jdt.core.dom.AST;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ASTNode;
import org.eclipse.che.ide.ext.java.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ArrayCreation;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ArrayInitializer;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ArrayType;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Assignment;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Block;
import org.eclipse.che.ide.ext.java.jdt.core.dom.BodyDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.CastExpression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.CatchClause;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ConditionalExpression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.DoStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.EnhancedForStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Expression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ExpressionStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ForStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.IBinding;
import org.eclipse.che.ide.ext.java.jdt.core.dom.IMethodBinding;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ITypeBinding;
import org.eclipse.che.ide.ext.java.jdt.core.dom.IVariableBinding;
import org.eclipse.che.ide.ext.java.jdt.core.dom.IfStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.InfixExpression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Initializer;
import org.eclipse.che.ide.ext.java.jdt.core.dom.LabeledStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.MethodDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.MethodInvocation;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Modifier;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Name;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.PrimitiveType;
import org.eclipse.che.ide.ext.java.jdt.core.dom.SimpleName;
import org.eclipse.che.ide.ext.java.jdt.core.dom.SimpleType;
import org.eclipse.che.ide.ext.java.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Statement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.StringLiteral;
import org.eclipse.che.ide.ext.java.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.che.ide.ext.java.jdt.core.dom.SwitchCase;
import org.eclipse.che.ide.ext.java.jdt.core.dom.SwitchStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.SynchronizedStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ThisExpression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.TryStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Type;
import org.eclipse.che.ide.ext.java.jdt.core.dom.TypeDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.UnionType;
import org.eclipse.che.ide.ext.java.jdt.core.dom.VariableDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.che.ide.ext.java.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.che.ide.ext.java.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.WhileStatement;
import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.codemanipulation.ASTResolving;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.Bindings;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.LinkedNodeFinder;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.TokenScanner;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.fix.CleanUpConstants;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.fix.CleanUpOptions;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.fix.ControlStatementsCleanUp;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.fix.ControlStatementsFix;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.fix.ICleanUp;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.fix.IProposableFix;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.refactoring.code.PromoteTempToFieldRefactoring;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.refactoring.util.TightSourceRangeComputer;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.ASTRewriteCorrectionProposal;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.AssignToVariableAssistProposal;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.CUCorrectionProposal;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.ChangeCorrectionProposal;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.FixCorrectionProposal;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.proposals.LinkedCorrectionProposal;
import org.eclipse.che.ide.ext.java.jdt.quickassist.api.InvocationContext;
import org.eclipse.che.ide.ext.java.jdt.refactoring.Refactoring;
import org.eclipse.che.ide.ext.java.jdt.refactoring.RefactoringStatus;
import org.eclipse.che.ide.ext.java.jdt.refactoring.TextChange;
import org.eclipse.che.ide.ext.java.jdt.text.Document;
import org.eclipse.che.ide.runtime.CoreException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*/
public class QuickAssistProcessorImpl implements org.eclipse.che.ide.ext.java.jdt.quickassist.api.QuickAssistProcessor {
public static final String SPLIT_JOIN_VARIABLE_DECLARATION_ID =
"org.eclipse.jdt.ui.correction.splitJoinVariableDeclaration.assist"; //$NON-NLS-1$
public static final String CONVERT_FOR_LOOP_ID = "org.eclipse.jdt.ui.correction.convertForLoop.assist"; //$NON-NLS-1$
public static final String ASSIGN_TO_LOCAL_ID = "org.eclipse.jdt.ui.correction.assignToLocal.assist"; //$NON-NLS-1$
public static final String ASSIGN_TO_FIELD_ID = "org.eclipse.jdt.ui.correction.assignToField.assist"; //$NON-NLS-1$
public static final String ASSIGN_PARAM_TO_FIELD_ID = "org.eclipse.jdt.ui.correction.assignParamToField.assist"; //$NON-NLS-1$
public static final String ADD_BLOCK_ID = "org.eclipse.jdt.ui.correction.addBlock.assist"; //$NON-NLS-1$
public static final String EXTRACT_LOCAL_ID = "org.eclipse.jdt.ui.correction.extractLocal.assist"; //$NON-NLS-1$
public static final String EXTRACT_LOCAL_NOT_REPLACE_ID =
"org.eclipse.jdt.ui.correction.extractLocalNotReplaceOccurrences.assist"; //$NON-NLS-1$
public static final String EXTRACT_CONSTANT_ID = "org.eclipse.jdt.ui.correction.extractConstant.assist"; //$NON-NLS-1$
public static final String INLINE_LOCAL_ID = "org.eclipse.jdt.ui.correction.inlineLocal.assist"; //$NON-NLS-1$
public static final String CONVERT_LOCAL_TO_FIELD_ID = "org.eclipse.jdt.ui.correction.convertLocalToField.assist"; //$NON-NLS-1$
public static final String CONVERT_ANONYMOUS_TO_LOCAL_ID =
"org.eclipse.jdt.ui.correction.convertAnonymousToLocal.assist"; //$NON-NLS-1$
public static final String CONVERT_TO_STRING_BUFFER_ID =
"org.eclipse.jdt.ui.correction.convertToStringBuffer.assist"; //$NON-NLS-1$
public static final String CONVERT_TO_MESSAGE_FORMAT_ID =
"org.eclipse.jdt.ui.correction.convertToMessageFormat.assist"; //$NON-NLS-1$;
public QuickAssistProcessorImpl() {
super();
}
public boolean hasAssists(InvocationContext context) throws CoreException {
ASTNode coveringNode = context.getCoveringNode();
if (coveringNode != null) {
ArrayList<ASTNode> coveredNodes = AdvancedQuickAssistProcessor.getFullyCoveredNodes(context, coveringNode);
return getCatchClauseToThrowsProposals(context, coveringNode, null)
|| getPickoutTypeFromMulticatchProposals(context, coveringNode, coveredNodes, null)
|| getConvertToMultiCatchProposals(context, coveringNode, null)
|| getUnrollMultiCatchProposals(context, coveringNode, null)
// || getRenameLocalProposals(context, coveringNode, null, null)
// || getRenameRefactoringProposal(context, coveringNode, null, null)
|| getAssignToVariableProposals(context, coveringNode, null, null)
|| getUnWrapProposals(context, coveringNode, null)
|| getAssignParamToFieldProposals(context, coveringNode, null)
|| getJoinVariableProposals(context, coveringNode, null)
|| getAddFinallyProposals(context, coveringNode, null)
|| getAddElseProposals(context, coveringNode, null)
|| getSplitVariableProposals(context, coveringNode, null)
|| getAddBlockProposals(context, coveringNode, null)
|| getArrayInitializerToArrayCreation(context, coveringNode, null)
|| getCreateInSuperClassProposals(context, coveringNode, null)
|| getInvertEqualsProposal(context, coveringNode, null)
|| getConvertForLoopProposal(context, coveringNode, null)
|| getExtractVariableProposal(context, false, null)
|| getExtractMethodProposal(context, coveringNode, false, null)
|| getInlineLocalProposal(context, coveringNode, null)
|| getConvertLocalToFieldProposal(context, coveringNode, null)
// || getConvertAnonymousToNestedProposal(context, coveringNode, null)
|| getConvertIterableLoopProposal(context, coveringNode, null)
|| getRemoveBlockProposals(context, coveringNode, null)
|| getMakeVariableDeclarationFinalProposals(context, null)
|| getMissingCaseStatementProposals(context, coveringNode, null)
|| getConvertStringConcatenationProposals(context, null)
|| getInferDiamondArgumentsProposal(context, coveringNode, null, null);
}
return false;
}
public JavaCompletionProposal[] getAssists(InvocationContext context, IProblemLocation[] locations)
throws CoreException {
ASTNode coveringNode = context.getCoveringNode();
if (coveringNode != null) {
ArrayList<ASTNode> coveredNodes = AdvancedQuickAssistProcessor.getFullyCoveredNodes(context, coveringNode);
ArrayList<ICommandAccess> resultingCollections = new ArrayList<ICommandAccess>();
boolean noErrorsAtLocation = noErrorsAtLocation(locations);
// quick assists that show up also if there is an error/warning
// getRenameLocalProposals(context, coveringNode, locations, resultingCollections);
// getRenameRefactoringProposal(context, coveringNode, locations, resultingCollections);
getAssignToVariableProposals(context, coveringNode, locations, resultingCollections);
getAssignParamToFieldProposals(context, coveringNode, resultingCollections);
getInferDiamondArgumentsProposal(context, coveringNode, locations, resultingCollections);
if (noErrorsAtLocation) {
boolean problemsAtLocation = locations.length != 0;
getCatchClauseToThrowsProposals(context, coveringNode, resultingCollections);
getPickoutTypeFromMulticatchProposals(context, coveringNode, coveredNodes, resultingCollections);
getConvertToMultiCatchProposals(context, coveringNode, resultingCollections);
getUnrollMultiCatchProposals(context, coveringNode, resultingCollections);
getUnWrapProposals(context, coveringNode, resultingCollections);
getJoinVariableProposals(context, coveringNode, resultingCollections);
getSplitVariableProposals(context, coveringNode, resultingCollections);
getAddFinallyProposals(context, coveringNode, resultingCollections);
getAddElseProposals(context, coveringNode, resultingCollections);
getAddBlockProposals(context, coveringNode, resultingCollections);
getInvertEqualsProposal(context, coveringNode, resultingCollections);
getArrayInitializerToArrayCreation(context, coveringNode, resultingCollections);
getCreateInSuperClassProposals(context, coveringNode, resultingCollections);
getExtractVariableProposal(context, problemsAtLocation, resultingCollections);
getExtractMethodProposal(context, coveringNode, problemsAtLocation, resultingCollections);
getInlineLocalProposal(context, coveringNode, resultingCollections);
getConvertLocalToFieldProposal(context, coveringNode, resultingCollections);
// getConvertAnonymousToNestedProposal(context, coveringNode, resultingCollections);
if (!getConvertForLoopProposal(context, coveringNode, resultingCollections))
getConvertIterableLoopProposal(context, coveringNode, resultingCollections);
getRemoveBlockProposals(context, coveringNode, resultingCollections);
getMakeVariableDeclarationFinalProposals(context, resultingCollections);
getConvertStringConcatenationProposals(context, resultingCollections);
getMissingCaseStatementProposals(context, coveringNode, resultingCollections);
}
return resultingCollections.toArray(new JavaCompletionProposal[resultingCollections.size()]);
}
return null;
}
static boolean noErrorsAtLocation(IProblemLocation[] locations) {
if (locations != null) {
for (int i = 0; i < locations.length; i++) {
IProblemLocation location = locations[i];
if (location.isError()) {
if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(location.getMarkerType())
&& JavaCore.getOptionForConfigurableSeverity(location.getProblemId()) != null) {
// continue (only drop out for severe (non-optional) errors)
} else {
return false;
}
}
}
}
return true;
}
private static int getIndex(int offset, List<Statement> statements) {
for (int i = 0; i < statements.size(); i++) {
Statement s = statements.get(i);
if (offset < s.getStartPosition()) {
return i;
}
if (offset < s.getStartPosition() + s.getLength()) {
return -1;
}
}
return statements.size();
}
private static boolean getExtractMethodProposal(InvocationContext context, ASTNode coveringNode,
boolean problemsAtLocation, Collection<ICommandAccess> proposals) throws CoreException {
//TODO
// if (!(coveringNode instanceof Expression) && !(coveringNode instanceof Statement)
// && !(coveringNode instanceof Block))
// {
// return false;
// }
// if (coveringNode instanceof Block)
// {
// List<Statement> statements = ((Block)coveringNode).statements();
// int startIndex = getIndex(context.getSelectionOffset(), statements);
// if (startIndex == -1)
// return false;
// int endIndex = getIndex(context.getSelectionOffset() + context.getSelectionLength(), statements);
// if (endIndex == -1 || endIndex <= startIndex)
// return false;
// }
//
// if (proposals == null)
// {
// return true;
// }
//
// // final ICompilationUnit cu = context.getCompilationUnit();
// final ExtractMethodRefactoring extractMethodRefactoring =
// new ExtractMethodRefactoring(context.getDocument(), context.getSelectionOffset(),
// context.getSelectionLength());
// extractMethodRefactoring.setMethodName("extracted"); //$NON-NLS-1$
// if (extractMethodRefactoring.checkInitialConditions(new NullProgressMonitor()).isOK())
// {
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_extractmethod_description;
//// LinkedProposalModel linkedProposalModel = new LinkedProposalModel();
// extractMethodRefactoring.setLinkedProposalModel(linkedProposalModel);
//
// Images image = new Image(JavaClientBundle.INSTANCE.publicMethod());
// int relevance = problemsAtLocation ? 1 : 4;
// RefactoringCorrectionProposal proposal =
// new RefactoringCorrectionProposal(label, cu, extractMethodRefactoring, relevance, image);
// proposal.setLinkedProposalModel(linkedProposalModel);
// proposals.add(proposal);
// }
return false;
}
private static boolean getExtractVariableProposal(InvocationContext context, boolean problemsAtLocation,
Collection<ICommandAccess> proposals) throws CoreException {
// ASTNode node = context.getCoveredNode();
//
// if (!(node instanceof Expression))
// {
// if (context.getSelectionLength() != 0)
// {
// return false;
// }
// node = context.getCoveringNode();
// if (!(node instanceof Expression))
// {
// return false;
// }
// }
// final Expression expression = (Expression)node;
//
// ITypeBinding binding = expression.resolveTypeBinding();
// if (binding == null || Bindings.isVoidType(binding))
// {
// return false;
// }
// if (proposals == null)
// {
// return true;
// }
//
// int relevanceDrop;
// if (context.getSelectionLength() == 0)
// {
// relevanceDrop = 6;
// }
// else if (problemsAtLocation)
// {
// relevanceDrop = 3;
// }
// else
// {
// relevanceDrop = 0;
// }
//
//// final ICompilationUnit cu = context.getCompilationUnit();
// ExtractTempRefactoring extractTempRefactoring =
// new ExtractTempRefactoring(context.getASTRoot(), expression.getStartPosition(), expression.getLength());
// if (extractTempRefactoring.checkInitialConditions(new NullProgressMonitor()).isOK())
// {
//// LinkedProposalModel linkedProposalModel = new LinkedProposalModel();
// extractTempRefactoring.setLinkedProposalModel(linkedProposalModel);
// extractTempRefactoring.setCheckResultForCompileProblems(false);
//
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_extract_to_local_all_description();
// //TODO
// Images image = new Image();//JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL);
// RefactoringCorrectionProposal proposal =
// new RefactoringCorrectionProposal(label, cu, extractTempRefactoring, 6 - relevanceDrop, image)
// {
// @Override
// protected void init(Refactoring refactoring) throws CoreException
// {
// ExtractTempRefactoring etr = (ExtractTempRefactoring)refactoring;
// etr.setTempName(etr.guessTempName()); // expensive
// }
// };
// proposal.setCommandId(EXTRACT_LOCAL_ID);
//// proposal.setLinkedProposalModel(linkedProposalModel);
// proposals.add(proposal);
// }
//
// ExtractTempRefactoring extractTempRefactoringSelectedOnly =
// new ExtractTempRefactoring(context.getASTRoot(), expression.getStartPosition(), expression.getLength());
// extractTempRefactoringSelectedOnly.setReplaceAllOccurrences(false);
// if (extractTempRefactoringSelectedOnly.checkInitialConditions(new NullProgressMonitor()).isOK())
// {
//// LinkedProposalModel linkedProposalModel = new LinkedProposalModel();
// extractTempRefactoringSelectedOnly.setLinkedProposalModel(linkedProposalModel);
// extractTempRefactoringSelectedOnly.setCheckResultForCompileProblems(false);
//
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_extract_to_local_description();
// //TODO
// Images image = new Image();//JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_LOCAL);
// RefactoringCorrectionProposal proposal =
// new RefactoringCorrectionProposal(label, cu, extractTempRefactoringSelectedOnly, 5 - relevanceDrop, image)
// {
// @Override
// protected void init(Refactoring refactoring) throws CoreException
// {
// ExtractTempRefactoring etr = (ExtractTempRefactoring)refactoring;
// etr.setTempName(etr.guessTempName()); // expensive
// }
// };
// proposal.setCommandId(EXTRACT_LOCAL_NOT_REPLACE_ID);
// proposal.setLinkedProposalModel(linkedProposalModel);
// proposals.add(proposal);
// }
//
// ExtractConstantRefactoring extractConstRefactoring =
// new ExtractConstantRefactoring(context.getASTRoot(), expression.getStartPosition(), expression.getLength());
// if (extractConstRefactoring.checkInitialConditions(new NullProgressMonitor()).isOK())
// {
// // LinkedProposalModel linkedProposalModel = new LinkedProposalModel();
//// extractConstRefactoring.setLinkedProposalModel(linkedProposalModel);
// extractConstRefactoring.setCheckResultForCompileProblems(false);
//
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_extract_to_constant_description();
// Images image = new Image(JavaClientBundle.INSTANCE.local_var());
// RefactoringCorrectionProposal proposal =
// new RefactoringCorrectionProposal(label, cu, extractConstRefactoring, 4 - relevanceDrop, image)
// {
// @Override
// protected void init(Refactoring refactoring) throws CoreException
// {
// ExtractConstantRefactoring etr = (ExtractConstantRefactoring)refactoring;
// etr.setConstantName(etr.guessConstantName()); // expensive
// }
// };
// proposal.setCommandId(EXTRACT_CONSTANT_ID);
//// proposal.setLinkedProposalModel(linkedProposalModel);
// proposals.add(proposal);
// }
return false;
}
// private static boolean getConvertAnonymousToNestedProposal(IInvocationContext context, final ASTNode node,
// Collection<ICommandAccess> proposals) throws CoreException
// {
// if (!(node instanceof Name))
// return false;
//
// ASTNode normalized = ASTNodes.getNormalizedNode(node);
// if (normalized.getLocationInParent() != ClassInstanceCreation.TYPE_PROPERTY)
// return false;
//
// final AnonymousClassDeclaration anonymTypeDecl =
// ((ClassInstanceCreation)normalized.getParent()).getAnonymousClassDeclaration();
// if (anonymTypeDecl == null || anonymTypeDecl.resolveBinding() == null)
// {
// return false;
// }
//
// if (proposals == null)
// {
// return true;
// }
//
// final ICompilationUnit cu = context.getCompilationUnit();
// final ConvertAnonymousToNestedRefactoring refactoring = new ConvertAnonymousToNestedRefactoring(anonymTypeDecl);
//
// String extTypeName = ASTNodes.getSimpleNameIdentifier((Name)node);
// ITypeBinding anonymTypeBinding = anonymTypeDecl.resolveBinding();
// String className;
// if (anonymTypeBinding.getInterfaces().length == 0)
// {
// className =
// Messages.format(CorrectionMessages.INSTANCE.QuickAssistProcessor_name_extension_from_interface, extTypeName);
// }
// else
// {
// className = Messages.format(CorrectionMessages.INSTANCE.QuickAssistProcessor_name_extension_from_class, extTypeName);
// }
// String[][] existingTypes = ((IType)anonymTypeBinding.getJavaElement()).resolveType(className);
// int i = 1;
// while (existingTypes != null)
// {
// i++;
// existingTypes = ((IType)anonymTypeBinding.getJavaElement()).resolveType(className + i);
// }
// refactoring.setClassName(i == 1 ? className : className + i);
//
// if (refactoring.checkInitialConditions(new NullProgressMonitor()).isOK())
// {
// LinkedProposalModel linkedProposalModel = new LinkedProposalModel();
// refactoring.setLinkedProposalModel(linkedProposalModel);
//
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_convert_anonym_to_nested;
// Images image = new Image(); //TODO//JavaPlugin.getImageDescriptorRegistry().get(JavaElementImageProvider
// .getTypeImageDescriptor(true, false, Flags.AccPrivate, false));
// RefactoringCorrectionProposal proposal = new RefactoringCorrectionProposal(label, cu, refactoring, 5, image);
// proposal.setLinkedProposalModel(linkedProposalModel);
// proposal.setCommandId(CONVERT_ANONYMOUS_TO_LOCAL_ID);
// proposals.add(proposal);
// }
// return false;
// }
public static boolean getInferDiamondArgumentsProposal(InvocationContext context, ASTNode node,
IProblemLocation[] locations, Collection<ICommandAccess> resultingCollections) {
// ParameterizedType createdType = null;
//
// if (node instanceof Name)
// {
// Name name = ASTNodes.getTopMostName((Name)node);
// if (name.getLocationInParent() == SimpleType.NAME_PROPERTY)
// {
// SimpleType type = (SimpleType)name.getParent();
// if (type.getLocationInParent() == ParameterizedType.TYPE_PROPERTY)
// {
// createdType = (ParameterizedType)type.getParent();
// if (createdType.getLocationInParent() != ClassInstanceCreation.TYPE_PROPERTY)
// {
// return false;
// }
// }
// }
// }
// else if (node instanceof ParameterizedType)
// {
// createdType = (ParameterizedType)node;
// if (createdType.getLocationInParent() != ClassInstanceCreation.TYPE_PROPERTY)
// {
// return false;
// }
// }
// else if (node instanceof ClassInstanceCreation)
// {
// ClassInstanceCreation creation = (ClassInstanceCreation)node;
// Type type = creation.getType();
// if (type instanceof ParameterizedType)
// {
// createdType = (ParameterizedType)type;
// }
// }
//
// if (createdType == null || createdType.typeArguments().size() != 0)
// {
// return false;
// }
//
// ITypeBinding binding = createdType.resolveBinding();
// if (binding == null)
// {
// return false;
// }
//
// ITypeBinding[] typeArguments = binding.getTypeArguments();
// if (typeArguments.length == 0)
// {
// return false;
// }
//
// if (resultingCollections == null)
// {
// return true;
// }
//
// // don't add if already added as quick fix
// if (containsMatchingProblem(locations, IProblem.DiamondNotBelow17))
// return false;
//
// AST ast = node.getAST();
// ASTRewrite rewrite = ASTRewrite.create(ast);
// ImportRewrite importRewrite = StubUtility.createImportRewrite(context.getASTRoot(), true);
// ContextSensitiveImportRewriteContext importContext =
// new ContextSensitiveImportRewriteContext(context.getASTRoot(), createdType.getStartPosition(), importRewrite);
//
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_infer_diamond_description;
// //TODO
// Images image = new Image();//JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
// int relevance = locations == null ? 7 : 1; // if error -> higher than ReorgCorrectionsSubProcessor
// .getNeedHigherComplianceProposals()
// LinkedCorrectionProposal proposal =
// new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, relevance, image);
//
// ListRewrite argumentsRewrite = rewrite.getListRewrite(createdType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
// for (int i = 0; i < typeArguments.length; i++)
// {
// ITypeBinding typeArgument = typeArguments[i];
// Type argumentNode = importRewrite.addImport(typeArgument, ast, importContext);
// argumentsRewrite.insertLast(argumentNode, null);
// proposal.addLinkedPosition(rewrite.track(argumentNode), true, "arg" + i); //$NON-NLS-1$
// }
//
// resultingCollections.add(proposal);
return true;
}
private static boolean getJoinVariableProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
ASTNode parent = node.getParent();
VariableDeclarationFragment fragment = null;
boolean onFirstAccess = false;
if (node instanceof SimpleName && node.getLocationInParent() == Assignment.LEFT_HAND_SIDE_PROPERTY) {
onFirstAccess = true;
SimpleName name = (SimpleName)node;
IBinding binding = name.resolveBinding();
if (!(binding instanceof IVariableBinding)) {
return false;
}
ASTNode declaring = context.getASTRoot().findDeclaringNode(binding);
if (declaring instanceof VariableDeclarationFragment) {
fragment = (VariableDeclarationFragment)declaring;
} else {
return false;
}
} else if (parent instanceof VariableDeclarationFragment) {
fragment = (VariableDeclarationFragment)parent;
} else {
return false;
}
IVariableBinding binding = fragment.resolveBinding();
Expression initializer = fragment.getInitializer();
if ((initializer != null && initializer.getNodeType() != ASTNode.NULL_LITERAL) || binding == null
|| binding.isField()) {
return false;
}
if (!(fragment.getParent() instanceof VariableDeclarationStatement)) {
return false;
}
VariableDeclarationStatement statement = (VariableDeclarationStatement)fragment.getParent();
SimpleName[] names = LinkedNodeFinder.findByBinding(statement.getParent(), binding);
if (names.length <= 1 || names[0] != fragment.getName()) {
return false;
}
SimpleName firstAccess = names[1];
if (onFirstAccess) {
if (firstAccess != node) {
return false;
}
} else {
if (firstAccess.getLocationInParent() != Assignment.LEFT_HAND_SIDE_PROPERTY) {
return false;
}
}
Assignment assignment = (Assignment)firstAccess.getParent();
if (assignment.getLocationInParent() != ExpressionStatement.EXPRESSION_PROPERTY) {
return false;
}
ExpressionStatement assignParent = (ExpressionStatement)assignment.getParent();
if (resultingCollections == null) {
return true;
}
AST ast = statement.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
TightSourceRangeComputer sourceRangeComputer = new TightSourceRangeComputer();
sourceRangeComputer.addTightSourceNode(assignParent);
rewrite.setTargetSourceRangeComputer(sourceRangeComputer);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_joindeclaration_description();
Images image = Images.local_var;
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
proposal.setCommandId(SPLIT_JOIN_VARIABLE_DECLARATION_ID);
Expression placeholder = (Expression)rewrite.createMoveTarget(assignment.getRightHandSide());
rewrite.set(fragment, VariableDeclarationFragment.INITIALIZER_PROPERTY, placeholder, null);
if (onFirstAccess) {
// replace assignment with variable declaration
rewrite.replace(assignParent, rewrite.createMoveTarget(statement), null);
} else {
// different scopes -> remove assignments, set variable initializer
if (ASTNodes.isControlStatementBody(assignParent.getLocationInParent())) {
Block block = ast.newBlock();
rewrite.replace(assignParent, block, null);
} else {
rewrite.remove(assignParent, null);
}
}
// proposal.setEndPosition(rewrite.track(fragment.getName()));
resultingCollections.add(proposal);
return true;
}
private static boolean getSplitVariableProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
VariableDeclarationFragment fragment;
if (node instanceof VariableDeclarationFragment) {
fragment = (VariableDeclarationFragment)node;
} else if (node.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY) {
fragment = (VariableDeclarationFragment)node.getParent();
} else {
return false;
}
if (fragment.getInitializer() == null) {
return false;
}
Statement statement;
ASTNode fragParent = fragment.getParent();
if (fragParent instanceof VariableDeclarationStatement) {
statement = (VariableDeclarationStatement)fragParent;
} else if (fragParent instanceof VariableDeclarationExpression) {
if (fragParent.getLocationInParent() == TryStatement.RESOURCES_PROPERTY) {
return false;
}
statement = (Statement)fragParent.getParent();
} else {
return false;
}
// statement is ForStatement or VariableDeclarationStatement
ASTNode statementParent = statement.getParent();
StructuralPropertyDescriptor property = statement.getLocationInParent();
if (!property.isChildListProperty()) {
return false;
}
List<? extends ASTNode> list = (List<? extends ASTNode>)statementParent.getStructuralProperty(property);
if (resultingCollections == null) {
return true;
}
AST ast = statement.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_splitdeclaration_description();
Images image = Images.local_var;
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
boolean commandConflict = false;
for (Iterator<ICommandAccess> iterator = resultingCollections.iterator(); iterator.hasNext(); ) {
Object completionProposal = iterator.next();
if (completionProposal instanceof ChangeCorrectionProposal) {
if (SPLIT_JOIN_VARIABLE_DECLARATION_ID
.equals(((ChangeCorrectionProposal)completionProposal).getCommandId())) {
commandConflict = true;
}
}
}
if (!commandConflict) {
proposal.setCommandId(SPLIT_JOIN_VARIABLE_DECLARATION_ID);
}
Statement newStatement;
int insertIndex = list.indexOf(statement);
Expression placeholder = (Expression)rewrite.createMoveTarget(fragment.getInitializer());
ITypeBinding binding = fragment.getInitializer().resolveTypeBinding();
if (placeholder instanceof ArrayInitializer && binding != null && binding.isArray()) {
ArrayCreation creation = ast.newArrayCreation();
creation.setInitializer((ArrayInitializer)placeholder);
final ITypeBinding componentType = binding.getElementType();
Type type = null;
if (componentType.isPrimitive())
type = ast.newPrimitiveType(PrimitiveType.toCode(componentType.getName()));
else
type = ast.newSimpleType(ast.newSimpleName(componentType.getName()));
creation.setType(ast.newArrayType(type, binding.getDimensions()));
placeholder = creation;
}
Assignment assignment = ast.newAssignment();
assignment.setRightHandSide(placeholder);
assignment.setLeftHandSide(ast.newSimpleName(fragment.getName().getIdentifier()));
if (statement instanceof VariableDeclarationStatement) {
newStatement = ast.newExpressionStatement(assignment);
insertIndex += 1; // add after declaration
} else {
rewrite.replace(fragment.getParent(), assignment, null);
VariableDeclarationFragment newFrag = ast.newVariableDeclarationFragment();
newFrag.setName(ast.newSimpleName(fragment.getName().getIdentifier()));
newFrag.setExtraDimensions(fragment.getExtraDimensions());
VariableDeclarationExpression oldVarDecl = (VariableDeclarationExpression)fragParent;
VariableDeclarationStatement newVarDec = ast.newVariableDeclarationStatement(newFrag);
newVarDec.setType((Type)ASTNode.copySubtree(ast, oldVarDecl.getType()));
newVarDec.modifiers().addAll(ASTNodeFactory.newModifiers(ast, oldVarDecl.getModifiers()));
newStatement = newVarDec;
}
ListRewrite listRewriter = rewrite.getListRewrite(statementParent, (ChildListPropertyDescriptor)property);
listRewriter.insertAt(newStatement, insertIndex, null);
resultingCollections.add(proposal);
return true;
}
private static boolean getConvertStringConcatenationProposals(InvocationContext context,
Collection<ICommandAccess> resultingCollections) {
ASTNode node = context.getCoveringNode();
BodyDeclaration parentDecl = ASTResolving.findParentBodyDeclaration(node);
if (!(parentDecl instanceof MethodDeclaration || parentDecl instanceof Initializer))
return false;
AST ast = node.getAST();
ITypeBinding stringBinding = ast.resolveWellKnownType("java.lang.String"); //$NON-NLS-1$
if (node instanceof Expression && !(node instanceof InfixExpression)) {
node = node.getParent();
}
if (node instanceof VariableDeclarationFragment) {
node = ((VariableDeclarationFragment)node).getInitializer();
} else if (node instanceof Assignment) {
node = ((Assignment)node).getRightHandSide();
}
InfixExpression oldInfixExpression = null;
while (node instanceof InfixExpression) {
InfixExpression curr = (InfixExpression)node;
if (curr.resolveTypeBinding() == stringBinding && curr.getOperator() == InfixExpression.Operator.PLUS) {
oldInfixExpression = curr; // is a infix expression we can use
} else {
break;
}
node = node.getParent();
}
if (oldInfixExpression == null)
return false;
if (resultingCollections == null) {
return true;
}
LinkedCorrectionProposal stringBufferProposal =
getConvertToStringBufferProposal(context, ast, oldInfixExpression);
resultingCollections.add(stringBufferProposal);
ASTRewriteCorrectionProposal messageFormatProposal =
getConvertToMessageFormatProposal(context, ast, oldInfixExpression);
if (messageFormatProposal != null)
resultingCollections.add(messageFormatProposal);
return true;
}
private static LinkedCorrectionProposal getConvertToStringBufferProposal(InvocationContext context, AST ast,
InfixExpression oldInfixExpression) {
String bufferOrBuilderName;
if (true /*JavaModelUtil.is50OrHigher(cu.getJavaProject()) */) {
bufferOrBuilderName = "StringBuilder"; //$NON-NLS-1$
} else {
bufferOrBuilderName = "StringBuffer"; //$NON-NLS-1$
}
ASTRewrite rewrite = ASTRewrite.create(ast);
SimpleName existingBuffer = getEnclosingAppendBuffer(oldInfixExpression);
String mechanismName =
/*BasicElementLabels.getJavaElementName*/(existingBuffer == null ? bufferOrBuilderName : existingBuffer
.getIdentifier());
String label =
CorrectionMessages.INSTANCE.QuickAssistProcessor_convert_to_string_buffer_description(mechanismName);
Images image = Images.correction_change;
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
proposal.setCommandId(CONVERT_TO_STRING_BUFFER_ID);
Statement insertAfter;
String bufferName;
String groupID = "nameId"; //$NON-NLS-1$
ListRewrite listRewrite;
Statement enclosingStatement = ASTResolving.findParentStatement(oldInfixExpression);
if (existingBuffer != null) {
if (ASTNodes.isControlStatementBody(enclosingStatement.getLocationInParent())) {
Block newBlock = ast.newBlock();
listRewrite = rewrite.getListRewrite(newBlock, Block.STATEMENTS_PROPERTY);
insertAfter = null;
rewrite.replace(enclosingStatement, newBlock, null);
} else {
listRewrite =
rewrite.getListRewrite(enclosingStatement.getParent(),
(ChildListPropertyDescriptor)enclosingStatement.getLocationInParent());
insertAfter = enclosingStatement;
}
bufferName = existingBuffer.getIdentifier();
} else {
// create buffer
VariableDeclarationFragment frag = ast.newVariableDeclarationFragment();
// check if name is already in use and provide alternative
List<String> fExcludedVariableNames = Arrays.asList(ASTResolving.getUsedVariableNames(oldInfixExpression));
SimpleType bufferType = ast.newSimpleType(ast.newName(bufferOrBuilderName));
ClassInstanceCreation newBufferExpression = ast.newClassInstanceCreation();
String[] newBufferNames =
StubUtility.getVariableNameSuggestions(NamingConventions.VK_LOCAL, bufferOrBuilderName, 0,
fExcludedVariableNames, true);
bufferName = newBufferNames[0];
SimpleName bufferNameDeclaration = ast.newSimpleName(bufferName);
frag.setName(bufferNameDeclaration);
// proposal.addLinkedPosition(rewrite.track(bufferNameDeclaration), true, groupID);
// for (int i = 0; i < newBufferNames.length; i++)
// {
// proposal.addLinkedPositionProposal(groupID, newBufferNames[i], null);
// }
newBufferExpression.setType(bufferType);
frag.setInitializer(newBufferExpression);
VariableDeclarationStatement bufferDeclaration = ast.newVariableDeclarationStatement(frag);
bufferDeclaration.setType(ast.newSimpleType(ast.newName(bufferOrBuilderName)));
insertAfter = bufferDeclaration;
Statement statement = ASTResolving.findParentStatement(oldInfixExpression);
if (ASTNodes.isControlStatementBody(statement.getLocationInParent())) {
Block newBlock = ast.newBlock();
listRewrite = rewrite.getListRewrite(newBlock, Block.STATEMENTS_PROPERTY);
listRewrite.insertFirst(bufferDeclaration, null);
listRewrite.insertLast(rewrite.createMoveTarget(statement), null);
rewrite.replace(statement, newBlock, null);
} else {
listRewrite =
rewrite.getListRewrite(statement.getParent(),
(ChildListPropertyDescriptor)statement.getLocationInParent());
listRewrite.insertBefore(bufferDeclaration, statement, null);
}
}
List<Expression> operands = new ArrayList<Expression>();
collectInfixPlusOperands(oldInfixExpression, operands);
Statement lastAppend = insertAfter;
for (Iterator<Expression> iter = operands.iterator(); iter.hasNext(); ) {
Expression operand = iter.next();
MethodInvocation appendIncovationExpression = ast.newMethodInvocation();
appendIncovationExpression.setName(ast.newSimpleName("append")); //$NON-NLS-1$
SimpleName bufferNameReference = ast.newSimpleName(bufferName);
// If there was an existing name, don't offer to rename it
// if (existingBuffer == null)
// {
// proposal.addLinkedPosition(rewrite.track(bufferNameReference), true, groupID);
// }
appendIncovationExpression.setExpression(bufferNameReference);
appendIncovationExpression.arguments().add(rewrite.createCopyTarget(operand));
ExpressionStatement appendExpressionStatement = ast.newExpressionStatement(appendIncovationExpression);
if (lastAppend == null) {
listRewrite.insertFirst(appendExpressionStatement, null);
} else {
listRewrite.insertAfter(appendExpressionStatement, lastAppend, null);
}
lastAppend = appendExpressionStatement;
}
if (existingBuffer != null) {
// proposal.setEndPosition(rewrite.track(lastAppend));
if (insertAfter != null) {
rewrite.remove(enclosingStatement, null);
}
} else {
// replace old expression with toString
MethodInvocation bufferToString = ast.newMethodInvocation();
bufferToString.setName(ast.newSimpleName("toString")); //$NON-NLS-1$
SimpleName bufferNameReference = ast.newSimpleName(bufferName);
bufferToString.setExpression(bufferNameReference);
// proposal.addLinkedPosition(rewrite.track(bufferNameReference), true, groupID);
rewrite.replace(oldInfixExpression, bufferToString, null);
// proposal.setEndPosition(rewrite.track(bufferToString));
}
return proposal;
}
private static void collectInfixPlusOperands(Expression expression, List<Expression> collector) {
if (expression instanceof InfixExpression
&& ((InfixExpression)expression).getOperator() == InfixExpression.Operator.PLUS) {
InfixExpression infixExpression = (InfixExpression)expression;
collectInfixPlusOperands(infixExpression.getLeftOperand(), collector);
collectInfixPlusOperands(infixExpression.getRightOperand(), collector);
List<Expression> extendedOperands = infixExpression.extendedOperands();
for (Iterator<Expression> iter = extendedOperands.iterator(); iter.hasNext(); ) {
collectInfixPlusOperands(iter.next(), collector);
}
} else {
collector.add(expression);
}
}
/**
* Checks
* <ul>
* <li>whether the given infix expression is the argument of a StringBuilder#append() or
* StringBuffer#append() invocation, and</li>
* <li>the append method is called on a simple variable, and</li>
* <li>the invocation occurs in a statement (not as nested expression)</li>
* </ul>
*
* @param infixExpression
* the infix expression
* @return the name of the variable we were appending to, or <code>null</code> if not matching
*/
private static SimpleName getEnclosingAppendBuffer(InfixExpression infixExpression) {
if (infixExpression.getLocationInParent() == MethodInvocation.ARGUMENTS_PROPERTY) {
MethodInvocation methodInvocation = (MethodInvocation)infixExpression.getParent();
// ..not in an expression.. (e.g. not sb.append("high" + 5).append(6);)
if (methodInvocation.getParent() instanceof Statement) {
// ..of a function called append:
if ("append".equals(methodInvocation.getName().getIdentifier())) { //$NON-NLS-1$
Expression expression = methodInvocation.getExpression();
// ..and the append is being called on a Simple object:
if (expression instanceof SimpleName) {
IBinding binding = ((SimpleName)expression).resolveBinding();
if (binding instanceof IVariableBinding) {
String typeName = ((IVariableBinding)binding).getType().getQualifiedName();
// And the object's type is a StringBuilder or StringBuffer:
if ("java.lang.StringBuilder".equals(typeName) ||
"java.lang.StringBuffer".equals(typeName)) { //$NON-NLS-1$ //$NON-NLS-2$
return (SimpleName)expression;
}
}
}
}
}
}
return null;
}
private static ASTRewriteCorrectionProposal getConvertToMessageFormatProposal(InvocationContext context, AST ast,
InfixExpression oldInfixExpression) {
boolean is50OrHigher = true; //JavaModelUtil.is50OrHigher(cu.getJavaProject());
ASTRewrite rewrite = ASTRewrite.create(ast);
CompilationUnit root = context.getASTRoot();
ImportRewrite importRewrite = StubUtility.createImportRewrite(context.getDocument(), root, true);
ContextSensitiveImportRewriteContext importContext =
new ContextSensitiveImportRewriteContext(root, oldInfixExpression.getStartPosition(), importRewrite);
// collect operands
List<Expression> operands = new ArrayList<Expression>();
collectInfixPlusOperands(oldInfixExpression, operands);
List<Expression> formatArguments = new ArrayList<Expression>();
String formatString = ""; //$NON-NLS-1$
int i = 0;
for (Iterator<Expression> iterator = operands.iterator(); iterator.hasNext(); ) {
Expression operand = iterator.next();
if (operand instanceof StringLiteral) {
String value = ((StringLiteral)operand).getEscapedValue();
value = value.substring(1, value.length() - 1);
value = value.replaceAll("'", "''"); //$NON-NLS-1$ //$NON-NLS-2$
formatString += value;
} else {
formatString += "{" + i + "}"; //$NON-NLS-1$ //$NON-NLS-2$
Expression argument;
if (is50OrHigher) {
argument = (Expression)rewrite.createCopyTarget(operand);
} else {
ITypeBinding binding = operand.resolveTypeBinding();
if (binding == null)
return null;
argument = (Expression)rewrite.createCopyTarget(operand);
if (binding.isPrimitive()) {
ITypeBinding boxedBinding = Bindings.getBoxedTypeBinding(binding, ast);
if (boxedBinding != binding) {
Type boxedType = importRewrite.addImport(boxedBinding, ast, importContext);
ClassInstanceCreation cic = ast.newClassInstanceCreation();
cic.setType(boxedType);
cic.arguments().add(argument);
argument = cic;
}
}
}
formatArguments.add(argument);
i++;
}
}
if (formatArguments.size() == 0)
return null;
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_convert_to_message_format();
Images image = Images.correction_change;
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 0, context.getDocument(), image);
proposal.setCommandId(CONVERT_TO_MESSAGE_FORMAT_ID);
proposal.setImportRewrite(importRewrite);
String messageType = importRewrite.addImport("java.text.MessageFormat", importContext); //$NON-NLS-1$
MethodInvocation formatInvocation = ast.newMethodInvocation();
formatInvocation.setExpression(ast.newName(messageType));
formatInvocation.setName(ast.newSimpleName("format")); //$NON-NLS-1$
List<Expression> arguments = formatInvocation.arguments();
StringLiteral formatStringArgument = ast.newStringLiteral();
formatStringArgument.setEscapedValue("\"" + formatString + "\""); //$NON-NLS-1$ //$NON-NLS-2$
arguments.add(formatStringArgument);
if (is50OrHigher) {
for (Iterator<Expression> iterator = formatArguments.iterator(); iterator.hasNext(); ) {
arguments.add(iterator.next());
}
} else {
ArrayCreation objectArrayCreation = ast.newArrayCreation();
Type objectType = ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
ArrayType arrayType = ast.newArrayType(objectType);
objectArrayCreation.setType(arrayType);
ArrayInitializer arrayInitializer = ast.newArrayInitializer();
List<Expression> initializerExpressions = arrayInitializer.expressions();
for (Iterator<Expression> iterator = formatArguments.iterator(); iterator.hasNext(); ) {
initializerExpressions.add(iterator.next());
}
objectArrayCreation.setInitializer(arrayInitializer);
arguments.add(objectArrayCreation);
}
rewrite.replace(oldInfixExpression, formatInvocation, null);
return proposal;
}
public static boolean getAssignToVariableProposals(InvocationContext context, ASTNode node,
IProblemLocation[] locations, Collection<ICommandAccess> resultingCollections) {
Statement statement = ASTResolving.findParentStatement(node);
if (!(statement instanceof ExpressionStatement)) {
return false;
}
ExpressionStatement expressionStatement = (ExpressionStatement)statement;
Expression expression = expressionStatement.getExpression();
if (expression.getNodeType() == ASTNode.ASSIGNMENT) {
return false; // too confusing and not helpful
}
ITypeBinding typeBinding = expression.resolveTypeBinding();
typeBinding = Bindings.normalizeTypeBinding(typeBinding);
if (typeBinding == null) {
return false;
}
if (resultingCollections == null) {
return true;
}
// don't add if already added as quick fix
if (containsMatchingProblem(locations, IProblem.UnusedObjectAllocation))
return false;
AssignToVariableAssistProposal localProposal =
new AssignToVariableAssistProposal(AssignToVariableAssistProposal.LOCAL, expressionStatement, typeBinding, 3,
context.getDocument());
localProposal.setCommandId(ASSIGN_TO_LOCAL_ID);
resultingCollections.add(localProposal);
ASTNode type = ASTResolving.findParentType(expression);
if (type != null) {
AssignToVariableAssistProposal fieldProposal =
new AssignToVariableAssistProposal(AssignToVariableAssistProposal.FIELD, expressionStatement, typeBinding,
2, context.getDocument());
fieldProposal.setCommandId(ASSIGN_TO_FIELD_ID);
resultingCollections.add(fieldProposal);
}
return true;
}
private static boolean containsMatchingProblem(IProblemLocation[] locations, int problemId) {
if (locations != null) {
for (int i = 0; i < locations.length; i++) {
IProblemLocation location = locations[i];
if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(location.getMarkerType())
&& location.getProblemId() == problemId) {
return true;
}
}
}
return false;
}
private static boolean getAssignParamToFieldProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
node = ASTNodes.getNormalizedNode(node);
ASTNode parent = node.getParent();
if (!(parent instanceof SingleVariableDeclaration) || !(parent.getParent() instanceof MethodDeclaration)) {
return false;
}
SingleVariableDeclaration paramDecl = (SingleVariableDeclaration)parent;
IVariableBinding binding = paramDecl.resolveBinding();
MethodDeclaration methodDecl = (MethodDeclaration)parent.getParent();
if (binding == null || methodDecl.getBody() == null) {
return false;
}
ITypeBinding typeBinding = binding.getType();
if (typeBinding == null) {
return false;
}
if (resultingCollections == null) {
return true;
}
ITypeBinding parentType = Bindings.getBindingOfParentType(node);
if (parentType != null) {
// assign to existing fields
CompilationUnit root = context.getASTRoot();
IVariableBinding[] declaredFields = parentType.getDeclaredFields();
boolean isStaticContext = ASTResolving.isInStaticContext(node);
for (int i = 0; i < declaredFields.length; i++) {
IVariableBinding curr = declaredFields[i];
if (isStaticContext == Modifier.isStatic(curr.getModifiers())
&& typeBinding.isAssignmentCompatible(curr.getType())) {
ASTNode fieldDeclFrag = root.findDeclaringNode(curr);
if (fieldDeclFrag instanceof VariableDeclarationFragment) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment)fieldDeclFrag;
if (fragment.getInitializer() == null) {
resultingCollections.add(new AssignToVariableAssistProposal(paramDecl, fragment, typeBinding, 1,
context.getDocument()));
}
}
}
}
}
AssignToVariableAssistProposal fieldProposal =
new AssignToVariableAssistProposal(paramDecl, null, typeBinding, 3, context.getDocument());
fieldProposal.setCommandId(ASSIGN_PARAM_TO_FIELD_ID);
resultingCollections.add(fieldProposal);
return true;
}
private static boolean getAddFinallyProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
TryStatement tryStatement = ASTResolving.findParentTryStatement(node);
if (tryStatement == null || tryStatement.getFinally() != null) {
return false;
}
Statement statement = ASTResolving.findParentStatement(node);
if (tryStatement != statement && tryStatement.getBody() != statement) {
return false; // an node inside a catch or finally block
}
if (resultingCollections == null) {
return true;
}
AST ast = tryStatement.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
Block finallyBody = ast.newBlock();
rewrite.set(tryStatement, TryStatement.FINALLY_PROPERTY, finallyBody, null);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_addfinallyblock_description();
Images image = Images.add_obj;
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
resultingCollections.add(proposal);
return true;
}
private static boolean getAddElseProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
if (!(node instanceof IfStatement)) {
return false;
}
IfStatement ifStatement = (IfStatement)node;
if (ifStatement.getElseStatement() != null) {
return false;
}
if (resultingCollections == null) {
return true;
}
AST ast = node.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
Block body = ast.newBlock();
rewrite.set(ifStatement, IfStatement.ELSE_STATEMENT_PROPERTY, body, null);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_addelseblock_description();
Images image = Images.add_obj;
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
resultingCollections.add(proposal);
return true;
}
public static boolean getCatchClauseToThrowsProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
CatchClause catchClause = (CatchClause)ASTResolving.findAncestor(node, ASTNode.CATCH_CLAUSE);
if (catchClause == null) {
return false;
}
Statement statement = ASTResolving.findParentStatement(node);
if (statement != catchClause.getParent() && statement != catchClause.getBody()) {
return false; // selection is in a statement inside the body
}
Type type = catchClause.getException().getType();
if (!type.isSimpleType() && !type.isUnionType()) {
return false;
}
BodyDeclaration bodyDeclaration = ASTResolving.findParentBodyDeclaration(catchClause);
if (!(bodyDeclaration instanceof MethodDeclaration) && !(bodyDeclaration instanceof Initializer)) {
return false;
}
if (resultingCollections == null) {
return true;
}
AST ast = bodyDeclaration.getAST();
Images image = Images.exceptionProp;
SimpleType selectedMultiCatchType = null;
if (type.isUnionType() && node instanceof Name) {
Name topMostName = ASTNodes.getTopMostName((Name)node);
ASTNode parent = topMostName.getParent();
if (parent instanceof SimpleType) {
selectedMultiCatchType = (SimpleType)parent;
}
}
if (bodyDeclaration instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration)bodyDeclaration;
ASTRewrite rewrite = ASTRewrite.create(ast);
if (selectedMultiCatchType != null) {
removeException(rewrite, (UnionType)type, selectedMultiCatchType);
addExceptionToThrows(ast, methodDeclaration, rewrite, selectedMultiCatchType);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_exceptiontothrows_description();
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 6, context.getDocument(), image);
resultingCollections.add(proposal);
} else {
removeCatchBlock(rewrite, catchClause);
if (type.isUnionType()) {
UnionType unionType = (UnionType)type;
List<Type> types = unionType.types();
for (Type elementType : types) {
if (!(elementType instanceof SimpleType))
return false;
addExceptionToThrows(ast, methodDeclaration, rewrite, (SimpleType)elementType);
}
} else {
addExceptionToThrows(ast, methodDeclaration, rewrite, (SimpleType)type);
}
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_catchclausetothrows_description();
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 4, context.getDocument(), image);
resultingCollections.add(proposal);
}
}
{ // for initializers or method declarations
ASTRewrite rewrite = ASTRewrite.create(ast);
if (selectedMultiCatchType != null) {
removeException(rewrite, (UnionType)type, selectedMultiCatchType);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_removeexception_description();
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 6, context.getDocument(), image);
resultingCollections.add(proposal);
} else {
removeCatchBlock(rewrite, catchClause);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_removecatchclause_description();
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 5, context.getDocument(), image);
resultingCollections.add(proposal);
}
}
return true;
}
private static void removeException(ASTRewrite rewrite, UnionType unionType, Type exception) {
ListRewrite listRewrite = rewrite.getListRewrite(unionType, UnionType.TYPES_PROPERTY);
List<Type> types = unionType.types();
for (Iterator<Type> iterator = types.iterator(); iterator.hasNext(); ) {
Type type = iterator.next();
if (type.equals(exception)) {
listRewrite.remove(type, null);
}
}
}
private static void addExceptionToThrows(AST ast, MethodDeclaration methodDeclaration, ASTRewrite rewrite,
SimpleType type2) {
ITypeBinding binding = type2.resolveBinding();
if (binding == null || isNotYetThrown(binding, methodDeclaration.thrownExceptions())) {
Name name = type2.getName();
Name newName = (Name)ASTNode.copySubtree(ast, name);
ListRewrite listRewriter =
rewrite.getListRewrite(methodDeclaration, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
listRewriter.insertLast(newName, null);
}
}
private static void removeCatchBlock(ASTRewrite rewrite, CatchClause catchClause) {
TryStatement tryStatement = (TryStatement)catchClause.getParent();
if (tryStatement.catchClauses().size() > 1 || tryStatement.getFinally() != null
|| (tryStatement.getAST().apiLevel() >= AST.JLS4 && !tryStatement.resources().isEmpty())) {
rewrite.remove(catchClause, null);
} else {
Block block = tryStatement.getBody();
List<Statement> statements = block.statements();
int nStatements = statements.size();
if (nStatements == 1) {
ASTNode first = statements.get(0);
rewrite.replace(tryStatement, rewrite.createCopyTarget(first), null);
} else if (nStatements > 1) {
ListRewrite listRewrite = rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
ASTNode first = statements.get(0);
ASTNode last = statements.get(statements.size() - 1);
ASTNode newStatement = listRewrite.createCopyTarget(first, last);
if (ASTNodes.isControlStatementBody(tryStatement.getLocationInParent())) {
Block newBlock = rewrite.getAST().newBlock();
newBlock.statements().add(newStatement);
newStatement = newBlock;
}
rewrite.replace(tryStatement, newStatement, null);
} else {
rewrite.remove(tryStatement, null);
}
}
}
private static boolean isNotYetThrown(ITypeBinding binding, List<Name> thrownExceptions) {
for (int i = 0; i < thrownExceptions.size(); i++) {
Name name = thrownExceptions.get(i);
ITypeBinding elem = (ITypeBinding)name.resolveBinding();
if (elem != null) {
if (Bindings.isSuperType(elem, binding)) { // existing exception is base class of new
return false;
}
}
}
return true;
}
private static boolean getPickoutTypeFromMulticatchProposals(InvocationContext context, ASTNode node,
ArrayList<ASTNode> coveredNodes,
Collection<ICommandAccess> resultingCollections) {
CatchClause catchClause = (CatchClause)ASTResolving.findAncestor(node, ASTNode.CATCH_CLAUSE);
if (catchClause == null) {
return false;
}
Statement statement = ASTResolving.findParentStatement(node);
if (statement != catchClause.getParent() && statement != catchClause.getBody()) {
return false; // selection is in a statement inside the body
}
Type type = catchClause.getException().getType();
if (!type.isUnionType()) {
return false;
}
SimpleType selectedMultiCatchType = null;
if (type.isUnionType() && node instanceof Name) {
Name topMostName = ASTNodes.getTopMostName((Name)node);
ASTNode parent = topMostName.getParent();
if (parent instanceof SimpleType) {
selectedMultiCatchType = (SimpleType)parent;
}
}
boolean multipleExceptions = coveredNodes.size() > 1;
if ((selectedMultiCatchType == null) && (!(node instanceof UnionType) || !multipleExceptions)) {
return false;
}
if (!multipleExceptions) {
coveredNodes.add(selectedMultiCatchType);
}
BodyDeclaration bodyDeclaration = ASTResolving.findParentBodyDeclaration(catchClause);
if (!(bodyDeclaration instanceof MethodDeclaration) && !(bodyDeclaration instanceof Initializer)) {
return false;
}
if (resultingCollections == null) {
return true;
}
AST ast = bodyDeclaration.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
CatchClause newCatchClause = ast.newCatchClause();
SingleVariableDeclaration newSingleVariableDeclaration = ast.newSingleVariableDeclaration();
UnionType newUnionType = ast.newUnionType();
List<Type> types = newUnionType.types();
for (int i = 0; i < coveredNodes.size(); i++) {
ASTNode typeNode = coveredNodes.get(i);
types.add((Type)rewrite.createCopyTarget(typeNode));
rewrite.remove(typeNode, null);
}
newSingleVariableDeclaration.setType(newUnionType);
newSingleVariableDeclaration.setName((SimpleName)rewrite.createCopyTarget(catchClause.getException().getName()));
newCatchClause.setException(newSingleVariableDeclaration);
setCatchClauseBody(newCatchClause, rewrite, catchClause);
TryStatement tryStatement = (TryStatement)catchClause.getParent();
ListRewrite listRewrite = rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY);
listRewrite.insertAfter(newCatchClause, catchClause, null);
Images image = Images.exceptionProp;
String label =
!multipleExceptions ? CorrectionMessages.INSTANCE
.QuickAssistProcessor_move_exception_to_separate_catch_block()
: CorrectionMessages.INSTANCE
.QuickAssistProcessor_move_exceptions_to_separate_catch_block();
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 6, context.getDocument(), image);
resultingCollections.add(proposal);
return true;
}
private static boolean getConvertToMultiCatchProposals(InvocationContext context, ASTNode covering,
Collection<ICommandAccess> resultingCollections) {
//TODO Java 7
// if (!JavaModelUtil.is17OrHigher(context.getCompilationUnit().getJavaProject()))
return false;
// CatchClause catchClause = (CatchClause)ASTResolving.findAncestor(covering, ASTNode.CATCH_CLAUSE);
// if (catchClause == null)
// {
// return false;
// }
//
// Statement statement = ASTResolving.findParentStatement(covering);
// if (statement != catchClause.getParent() && statement != catchClause.getBody())
// {
// return false; // selection is in a statement inside the body
// }
//
// Type type1 = catchClause.getException().getType();
// SimpleType selectedMultiCatchType = null;
// if (type1.isUnionType() && covering instanceof Name)
// {
// Name topMostName = ASTNodes.getTopMostName((Name)covering);
// ASTNode parent = topMostName.getParent();
// if (parent instanceof SimpleType)
// {
// selectedMultiCatchType = (SimpleType)parent;
// }
// }
// if (selectedMultiCatchType != null)
// return false;
//
// TryStatement tryStatement = (TryStatement)catchClause.getParent();
// List<CatchClause> catchClauses = tryStatement.catchClauses();
// if (catchClauses.size() <= 1)
// return false;
//
// String commonSource = null;
// try
// {
// IBuffer buffer = context.getCompilationUnit().getBuffer();
// for (Iterator<CatchClause> iterator = catchClauses.iterator(); iterator.hasNext();)
// {
// CatchClause catchClause1 = iterator.next();
// Block body = catchClause1.getBody();
// String source = buffer.getText(body.getStartPosition(), body.getLength());
// if (commonSource == null)
// {
// commonSource = source;
// }
// else
// {
// if (!commonSource.equals(source))
// return false;
// }
// }
// }
// catch (JavaModelException e)
// {
// return false;
// }
//
// if (resultingCollections == null)
// return true;
//
// AST ast = covering.getAST();
// ASTRewrite rewrite = ASTRewrite.create(ast);
// TightSourceRangeComputer sourceRangeComputer = new TightSourceRangeComputer();
// sourceRangeComputer.addTightSourceNode(catchClauses.get(catchClauses.size() - 1));
// rewrite.setTargetSourceRangeComputer(sourceRangeComputer);
//
// CatchClause firstCatchClause = catchClauses.get(0);
//
// UnionType newUnionType = ast.newUnionType();
// List<Type> types = newUnionType.types();
// for (Iterator<CatchClause> iterator = catchClauses.iterator(); iterator.hasNext();)
// {
// CatchClause catchClause1 = iterator.next();
// Type type = catchClause1.getException().getType();
// if (type instanceof UnionType)
// {
// List<Type> types2 = ((UnionType)type).types();
// for (Iterator<Type> iterator2 = types2.iterator(); iterator2.hasNext();)
// {
// types.add((Type)rewrite.createCopyTarget(iterator2.next()));
// }
// }
// else
// {
// types.add((Type)rewrite.createCopyTarget(type));
// }
// }
//
// SingleVariableDeclaration newExceptionDeclaration = ast.newSingleVariableDeclaration();
// newExceptionDeclaration.setType(newUnionType);
// newExceptionDeclaration.setName((SimpleName)rewrite.createCopyTarget(firstCatchClause.getException().getName()));
// rewrite.replace(firstCatchClause.getException(), newExceptionDeclaration, null);
//
// for (int i = 1; i < catchClauses.size(); i++)
// {
// rewrite.remove(catchClauses.get(i), null);
// }
//
// Images image = new Image();//TODO JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_convert_to_single_multicatch_block;
// ASTRewriteCorrectionProposal proposal =
// new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 2, image);
// resultingCollections.add(proposal);
// return true;
}
private static boolean getUnrollMultiCatchProposals(InvocationContext context, ASTNode covering,
Collection<ICommandAccess> resultingCollections) {
//TODO Java 7
// if (!JavaModelUtil.is17OrHigher(context.getCompilationUnit().getJavaProject()))
return false;
// CatchClause catchClause = (CatchClause)ASTResolving.findAncestor(covering, ASTNode.CATCH_CLAUSE);
// if (catchClause == null)
// {
// return false;
// }
//
// Statement statement = ASTResolving.findParentStatement(covering);
// if (statement != catchClause.getParent() && statement != catchClause.getBody())
// {
// return false; // selection is in a statement inside the body
// }
//
// Type type1 = catchClause.getException().getType();
// SimpleType selectedMultiCatchType = null;
// if (type1.isUnionType() && covering instanceof Name)
// {
// Name topMostName = ASTNodes.getTopMostName((Name)covering);
// ASTNode parent = topMostName.getParent();
// if (parent instanceof SimpleType)
// {
// selectedMultiCatchType = (SimpleType)parent;
// }
// }
// if (selectedMultiCatchType != null)
// return false;
//
// SingleVariableDeclaration singleVariableDeclaration = catchClause.getException();
// Type type = singleVariableDeclaration.getType();
// if (!(type instanceof UnionType))
// return false;
//
// if (resultingCollections == null)
// return true;
//
// AST ast = covering.getAST();
// ASTRewrite rewrite = ASTRewrite.create(ast);
//
// TryStatement tryStatement = (TryStatement)catchClause.getParent();
// ListRewrite listRewrite = rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY);
//
// UnionType unionType = (UnionType)type;
// List<Type> types = unionType.types();
// for (int i = types.size() - 1; i >= 0; i--)
// {
// Type type2 = types.get(i);
// CatchClause newCatchClause = ast.newCatchClause();
//
// SingleVariableDeclaration newSingleVariableDeclaration = ast.newSingleVariableDeclaration();
// newSingleVariableDeclaration.setType((Type)rewrite.createCopyTarget(type2));
// newSingleVariableDeclaration
// .setName((SimpleName)rewrite.createCopyTarget(singleVariableDeclaration.getName()));
// newCatchClause.setException(newSingleVariableDeclaration);
// setCatchClauseBody(newCatchClause, rewrite, catchClause);
// listRewrite.insertAfter(newCatchClause, catchClause, null);
// }
// rewrite.remove(catchClause, null);
//
// Images image = new Image();//TODO JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks;
// ASTRewriteCorrectionProposal proposal =
// new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 2, image);
// resultingCollections.add(proposal);
// return true;
}
private static void setCatchClauseBody(CatchClause newCatchClause, ASTRewrite rewrite, CatchClause catchClause) {
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285
// newCatchClause.setBody((Block) rewrite.createCopyTarget(catchClause.getBody()));
//newCatchClause#setBody() destroys the formatting, hence copy statement by statement.
List<Statement> statements = catchClause.getBody().statements();
for (Iterator<Statement> iterator2 = statements.iterator(); iterator2.hasNext(); ) {
newCatchClause.getBody().statements().add(rewrite.createCopyTarget(iterator2.next()));
}
}
private static boolean getRenameLocalProposals(InvocationContext context, ASTNode node,
IProblemLocation[] locations, Collection<ICommandAccess> resultingCollections) {
//TODO Linked edit
// if (!(node instanceof SimpleName))
// {
// return false;
// }
// SimpleName name = (SimpleName)node;
// IBinding binding = name.resolveBinding();
// if (binding != null && binding.getKind() == IBinding.PACKAGE)
// {
// return false;
// }
//
// if (containsQuickFixableRenameLocal(locations))
// {
// return false;
// }
//
// if (resultingCollections == null)
// {
// return true;
// }
//
// LinkedNamesAssistProposal proposal = new LinkedNamesAssistProposal(context, name);
// if (locations.length != 0)
// {
// proposal.setRelevance(1);
// }
//
// resultingCollections.add(proposal);
// return true;
return false;
}
//TODO
// private static boolean getRenameRefactoringProposal(IInvocationContext context, ASTNode node, IProblemLocation[] locations,
// Collection<ICommandAccess> resultingCollections)
// throws CoreException {
// if (!(context instanceof AssistContext)) {
// return false;
// }
// IEditorPart editor= ((AssistContext)context).getEditor();
// if (!(editor instanceof JavaEditor))
// return false;
//
// if (!(node instanceof SimpleName)) {
// return false;
// }
// SimpleName name= (SimpleName) node;
// IBinding binding= name.resolveBinding();
// if (binding == null) {
// return false;
// }
//
// IJavaElement javaElement= binding.getJavaElement();
// if (javaElement == null || !RefactoringAvailabilityTester.isRenameElementAvailable(javaElement)) {
// return false;
// }
//
// if (resultingCollections == null) {
// return true;
// }
//
// RenameRefactoringProposal proposal= new RenameRefactoringProposal((JavaEditor) editor);
// if (locations.length != 0) {
// proposal.setRelevance(1);
// } else if (containsQuickFixableRenameLocal(locations)) {
// proposal.setRelevance(7);
// }
//
//
// resultingCollections.add(proposal);
// return true;
// }
private static boolean containsQuickFixableRenameLocal(IProblemLocation[] locations) {
if (locations != null) {
for (int i = 0; i < locations.length; i++) {
IProblemLocation location = locations[i];
if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(location.getMarkerType())) {
switch (location.getProblemId()) {
case IProblem.LocalVariableHidingLocalVariable:
case IProblem.LocalVariableHidingField:
case IProblem.FieldHidingLocalVariable:
case IProblem.FieldHidingField:
case IProblem.ArgumentHidingLocalVariable:
case IProblem.ArgumentHidingField:
return true;
}
}
}
}
return false;
}
public static ASTNode getCopyOfInner(ASTRewrite rewrite, ASTNode statement, boolean toControlStatementBody) {
if (statement.getNodeType() == ASTNode.BLOCK) {
Block block = (Block)statement;
List<Statement> innerStatements = block.statements();
int nStatements = innerStatements.size();
if (nStatements == 1) {
return rewrite.createCopyTarget(innerStatements.get(0));
} else if (nStatements > 1) {
if (toControlStatementBody) {
return rewrite.createCopyTarget(block);
}
ListRewrite listRewrite = rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
ASTNode first = innerStatements.get(0);
ASTNode last = innerStatements.get(nStatements - 1);
return listRewrite.createCopyTarget(first, last);
}
return null;
} else {
return rewrite.createCopyTarget(statement);
}
}
private static boolean getUnWrapProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
ASTNode outer = node;
Block block = null;
if (outer.getNodeType() == ASTNode.BLOCK) {
block = (Block)outer;
outer = block.getParent();
}
ASTNode body = null;
String label = null;
if (outer instanceof IfStatement) {
IfStatement ifStatement = (IfStatement)outer;
Statement elseBlock = ifStatement.getElseStatement();
if (elseBlock == null || elseBlock instanceof Block && ((Block)elseBlock).statements().isEmpty()) {
body = ifStatement.getThenStatement();
}
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_ifstatement();
} else if (outer instanceof WhileStatement) {
body = ((WhileStatement)outer).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_whilestatement();
} else if (outer instanceof ForStatement) {
body = ((ForStatement)outer).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_forstatement();
} else if (outer instanceof EnhancedForStatement) {
body = ((EnhancedForStatement)outer).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_forstatement();
} else if (outer instanceof SynchronizedStatement) {
body = ((SynchronizedStatement)outer).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_synchronizedstatement();
} else if (outer instanceof SimpleName && outer.getParent() instanceof LabeledStatement) {
body = ((LabeledStatement)outer.getParent()).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_labeledstatement();
} else if (outer instanceof LabeledStatement) {
body = ((LabeledStatement)outer).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_labeledstatement();
} else if (outer instanceof DoStatement) {
body = ((DoStatement)outer).getBody();
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_dostatement();
} else if (outer instanceof TryStatement) {
TryStatement tryStatement = (TryStatement)outer;
if (tryStatement.catchClauses().isEmpty()
&& (tryStatement.getAST().apiLevel() >= AST.JLS4 && tryStatement.resources().isEmpty())) {
body = tryStatement.getBody();
}
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_trystatement();
} else if (outer instanceof AnonymousClassDeclaration) {
List<BodyDeclaration> decls = ((AnonymousClassDeclaration)outer).bodyDeclarations();
for (int i = 0; i < decls.size(); i++) {
BodyDeclaration elem = decls.get(i);
if (elem instanceof MethodDeclaration) {
Block curr = ((MethodDeclaration)elem).getBody();
if (curr != null && !curr.statements().isEmpty()) {
if (body != null) {
return false;
}
body = curr;
}
} else if (elem instanceof TypeDeclaration) {
return false;
}
}
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_anonymous();
outer = ASTResolving.findParentStatement(outer);
if (outer == null) {
return false; // private Object o= new Object() { ... };
}
} else if (outer instanceof Block) {
// -> a block in a block
body = block;
outer = block;
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_block();
} else if (outer instanceof ParenthesizedExpression) {
//ParenthesizedExpression expression= (ParenthesizedExpression) outer;
//body= expression.getExpression();
//label= CorrectionMessages.INSTANCE.getString("QuickAssistProcessor.unwrap.parenthesis"); //$NON-NLS-1$
} else if (outer instanceof MethodInvocation) {
MethodInvocation invocation = (MethodInvocation)outer;
if (invocation.arguments().size() == 1) {
body = (ASTNode)invocation.arguments().get(0);
if (invocation.getParent().getNodeType() == ASTNode.EXPRESSION_STATEMENT) {
int kind = body.getNodeType();
if (kind != ASTNode.ASSIGNMENT && kind != ASTNode.PREFIX_EXPRESSION
&& kind != ASTNode.POSTFIX_EXPRESSION && kind != ASTNode.METHOD_INVOCATION
&& kind != ASTNode.SUPER_METHOD_INVOCATION) {
body = null;
}
}
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_unwrap_methodinvocation();
}
}
if (body == null) {
return false;
}
ASTRewrite rewrite = ASTRewrite.create(outer.getAST());
ASTNode inner = getCopyOfInner(rewrite, body, ASTNodes.isControlStatementBody(outer.getLocationInParent()));
if (inner == null) {
return false;
}
if (resultingCollections == null) {
return true;
}
rewrite.replace(outer, inner, null);
Images image = Images.exceptionProp;
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
resultingCollections.add(proposal);
return true;
}
private static boolean isControlStatementWithBlock(ASTNode node) {
switch (node.getNodeType()) {
case ASTNode.IF_STATEMENT:
case ASTNode.WHILE_STATEMENT:
case ASTNode.FOR_STATEMENT:
case ASTNode.DO_STATEMENT:
return true;
default:
return false;
}
}
private static boolean getRemoveBlockProposals(InvocationContext context, ASTNode coveringNode,
Collection<ICommandAccess> resultingCollections) {
IProposableFix[] fixes =
ControlStatementsFix.createRemoveBlockFix(context.getASTRoot(), coveringNode, context.getDocument());
if (fixes != null) {
if (resultingCollections == null) {
return true;
}
Map<String, String> options = new HashMap<String, String>();
options.put(CleanUpConstants.CONTROL_STATEMENTS_USE_BLOCKS, CleanUpOptions.TRUE);
options.put(CleanUpConstants.CONTROL_STATMENTS_USE_BLOCKS_NEVER, CleanUpOptions.TRUE);
ICleanUp cleanUp = new ControlStatementsCleanUp(options);
for (int i = 0; i < fixes.length; i++) {
IProposableFix fix = fixes[i];
Images image = Images.correction_change;
FixCorrectionProposal proposal = new FixCorrectionProposal(fix, cleanUp, 0, image, context);
resultingCollections.add(proposal);
}
return true;
}
return false;
}
private static boolean getAddBlockProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
if (!(node instanceof Statement)) {
return false;
}
/*
* only show the quick assist when the selection is of the control statement keywords (if, else, while,...)
* but not inside the statement or the if expression.
*/
if (!isControlStatementWithBlock(node) && isControlStatementWithBlock(node.getParent())) {
int statementStart = node.getStartPosition();
int statementEnd = statementStart + node.getLength();
int offset = context.getSelectionOffset();
int length = context.getSelectionLength();
if (length == 0) {
if (offset != statementEnd) { // cursor at end
return false;
}
} else {
if (offset > statementStart || offset + length < statementEnd) { // statement selected
return false;
}
}
node = node.getParent();
}
StructuralPropertyDescriptor childProperty = null;
ASTNode child = null;
switch (node.getNodeType()) {
case ASTNode.IF_STATEMENT:
ASTNode then = ((IfStatement)node).getThenStatement();
ASTNode elseStatement = ((IfStatement)node).getElseStatement();
if ((then instanceof Block) && (elseStatement instanceof Block || elseStatement == null)) {
break;
}
int thenEnd = then.getStartPosition() + then.getLength();
int selectionEnd = context.getSelectionOffset() + context.getSelectionLength();
if (!(then instanceof Block)) {
if (selectionEnd <= thenEnd) {
childProperty = IfStatement.THEN_STATEMENT_PROPERTY;
child = then;
break;
} else if (elseStatement != null && selectionEnd < elseStatement.getStartPosition()) {
// find out if we are before or after the 'else' keyword
try {
TokenScanner scanner = new TokenScanner(context.getDocument());
int elseTokenStart = scanner.getNextStartOffset(thenEnd, true);
if (selectionEnd < elseTokenStart) {
childProperty = IfStatement.THEN_STATEMENT_PROPERTY;
child = then;
break;
}
} catch (CoreException e) {
// ignore
}
}
}
if (elseStatement != null && !(elseStatement instanceof Block) && context.getSelectionOffset() >= thenEnd) {
childProperty = IfStatement.ELSE_STATEMENT_PROPERTY;
child = elseStatement;
}
break;
case ASTNode.WHILE_STATEMENT:
ASTNode whileBody = ((WhileStatement)node).getBody();
if (!(whileBody instanceof Block)) {
childProperty = WhileStatement.BODY_PROPERTY;
child = whileBody;
}
break;
case ASTNode.FOR_STATEMENT:
ASTNode forBody = ((ForStatement)node).getBody();
if (!(forBody instanceof Block)) {
childProperty = ForStatement.BODY_PROPERTY;
child = forBody;
}
break;
case ASTNode.DO_STATEMENT:
ASTNode doBody = ((DoStatement)node).getBody();
if (!(doBody instanceof Block)) {
childProperty = DoStatement.BODY_PROPERTY;
child = doBody;
}
break;
default:
}
if (child == null) {
return false;
}
if (resultingCollections == null) {
return true;
}
AST ast = node.getAST();
{
ASTRewrite rewrite = ASTRewrite.create(ast);
ASTNode childPlaceholder = rewrite.createMoveTarget(child);
Block replacingBody = ast.newBlock();
replacingBody.statements().add(childPlaceholder);
rewrite.set(node, childProperty, replacingBody, null);
String label;
if (childProperty == IfStatement.THEN_STATEMENT_PROPERTY) {
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_replacethenwithblock_description();
} else if (childProperty == IfStatement.ELSE_STATEMENT_PROPERTY) {
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_replaceelsewithblock_description();
} else {
label = CorrectionMessages.INSTANCE.QuickAssistProcessor_replacebodywithblock_description();
}
Images image = Images.correction_change;
LinkedCorrectionProposal proposal =
new LinkedCorrectionProposal(label, rewrite, 5, context.getDocument(), image);
proposal.setCommandId(ADD_BLOCK_ID);
// proposal.setEndPosition(rewrite.track(child));
resultingCollections.add(proposal);
}
if (node.getNodeType() == ASTNode.IF_STATEMENT) {
ASTRewrite rewrite = ASTRewrite.create(ast);
while (node.getLocationInParent() == IfStatement.ELSE_STATEMENT_PROPERTY) {
node = node.getParent();
}
boolean missingBlockFound = false;
boolean foundElse = false;
IfStatement ifStatement;
Statement thenStatment;
Statement elseStatment;
do {
ifStatement = (IfStatement)node;
thenStatment = ifStatement.getThenStatement();
elseStatment = ifStatement.getElseStatement();
if (!(thenStatment instanceof Block)) {
ASTNode childPlaceholder1 = rewrite.createMoveTarget(thenStatment);
Block replacingBody1 = ast.newBlock();
replacingBody1.statements().add(childPlaceholder1);
rewrite.set(ifStatement, IfStatement.THEN_STATEMENT_PROPERTY, replacingBody1, null);
if (thenStatment != child) {
missingBlockFound = true;
}
}
if (elseStatment != null) {
foundElse = true;
}
node = elseStatment;
}
while (elseStatment instanceof IfStatement);
if (elseStatment != null && !(elseStatment instanceof Block)) {
ASTNode childPlaceholder2 = rewrite.createMoveTarget(elseStatment);
Block replacingBody2 = ast.newBlock();
replacingBody2.statements().add(childPlaceholder2);
rewrite.set(ifStatement, IfStatement.ELSE_STATEMENT_PROPERTY, replacingBody2, null);
if (elseStatment != child) {
missingBlockFound = true;
}
}
if (missingBlockFound && foundElse) {
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_replacethenelsewithblock_description();
Images image = Images.correction_change;
ASTRewriteCorrectionProposal proposal =
new ASTRewriteCorrectionProposal(label, rewrite, 6, context.getDocument(), image);
resultingCollections.add(proposal);
}
}
return true;
}
private static boolean getInvertEqualsProposal(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
if (!(node instanceof MethodInvocation)) {
node = node.getParent();
if (!(node instanceof MethodInvocation)) {
return false;
}
}
MethodInvocation method = (MethodInvocation)node;
String identifier = method.getName().getIdentifier();
if (!"equals".equals(identifier) && !"equalsIgnoreCase".equals(identifier)) { //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
List<Expression> arguments = method.arguments();
if (arguments.size() != 1) { //overloaded equals w/ more than 1 argument
return false;
}
Expression right = arguments.get(0);
ITypeBinding binding = right.resolveTypeBinding();
if (binding != null && !(binding.isClass() || binding.isInterface())) { //overloaded equals w/ non-class/interface argument or null
return false;
}
if (resultingCollections == null) {
return true;
}
Expression left = method.getExpression();
AST ast = method.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
if (left == null) { // equals(x) -> x.equals(this)
MethodInvocation replacement = ast.newMethodInvocation();
replacement.setName((SimpleName)rewrite.createCopyTarget(method.getName()));
replacement.arguments().add(ast.newThisExpression());
replacement.setExpression((Expression)rewrite.createCopyTarget(right));
rewrite.replace(method, replacement, null);
} else if (right instanceof ThisExpression) { // x.equals(this) -> equals(x)
MethodInvocation replacement = ast.newMethodInvocation();
replacement.setName((SimpleName)rewrite.createCopyTarget(method.getName()));
replacement.arguments().add(rewrite.createCopyTarget(left));
rewrite.replace(method, replacement, null);
} else {
ASTNode leftExpression = left;
while (leftExpression instanceof ParenthesizedExpression) {
leftExpression = ((ParenthesizedExpression)left).getExpression();
}
rewrite.replace(right, rewrite.createCopyTarget(leftExpression), null);
if (right instanceof CastExpression || right instanceof Assignment || right instanceof ConditionalExpression
|| right instanceof InfixExpression) {
ParenthesizedExpression paren = ast.newParenthesizedExpression();
paren.setExpression((Expression)rewrite.createCopyTarget(right));
rewrite.replace(left, paren, null);
} else {
rewrite.replace(left, rewrite.createCopyTarget(right), null);
}
}
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_invertequals_description();
Images image = Images.correction_change;
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
resultingCollections.add(proposal);
return true;
}
private static boolean getArrayInitializerToArrayCreation(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
if (!(node instanceof ArrayInitializer)) {
return false;
}
ArrayInitializer initializer = (ArrayInitializer)node;
ASTNode parent = initializer.getParent();
while (parent instanceof ArrayInitializer) {
initializer = (ArrayInitializer)parent;
parent = parent.getParent();
}
ITypeBinding typeBinding = initializer.resolveTypeBinding();
if (!(parent instanceof VariableDeclaration) || typeBinding == null || !typeBinding.isArray()) {
return false;
}
if (resultingCollections == null) {
return true;
}
AST ast = node.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_typetoarrayInitializer_description();
Images image = Images.correction_change;
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, rewrite, 1, context.getDocument(), image);
ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(node, imports);
String typeName = imports.addImport(typeBinding, importRewriteContext);
ArrayCreation creation = ast.newArrayCreation();
creation.setInitializer((ArrayInitializer)rewrite.createMoveTarget(initializer));
creation.setType((ArrayType)ASTNodeFactory.newType(ast, typeName));
rewrite.replace(initializer, creation, null);
resultingCollections.add(proposal);
return true;
}
public static boolean getCreateInSuperClassProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) throws CoreException {
if (!(node instanceof SimpleName) || !(node.getParent() instanceof MethodDeclaration)) {
return false;
}
MethodDeclaration decl = (MethodDeclaration)node.getParent();
if (decl.getName() != node || decl.resolveBinding() == null || Modifier.isPrivate(decl.getModifiers())) {
return false;
}
CompilationUnit astRoot = context.getASTRoot();
IMethodBinding binding = decl.resolveBinding();
ITypeBinding[] paramTypes = binding.getParameterTypes();
ITypeBinding[] superTypes = Bindings.getAllSuperTypes(binding.getDeclaringClass());
if (resultingCollections == null) {
for (int i = 0; i < superTypes.length; i++) {
ITypeBinding curr = superTypes[i];
if (curr.isFromSource() && Bindings.findOverriddenMethodInType(curr, binding) == null) {
return true;
}
}
return false;
}
List<SingleVariableDeclaration> params = decl.parameters();
String[] paramNames = new String[paramTypes.length];
for (int i = 0; i < params.size(); i++) {
SingleVariableDeclaration param = params.get(i);
paramNames[i] = param.getName().getIdentifier();
}
for (int i = 0; i < superTypes.length; i++) {
ITypeBinding curr = superTypes[i];
if (curr.isFromSource()) {
IMethodBinding method = Bindings.findOverriddenMethodInType(curr, binding);
if (method == null) {
//TODO load class file
// ITypeBinding typeDecl = curr.getTypeDeclaration();
// ICompilationUnit targetCU = ASTResolving.findCompilationUnitForBinding(cu, astRoot, typeDecl);
// if (targetCU != null)
// {
// String label =
// Messages.format(
// CorrectionMessages.INSTANCE.QuickAssistProcessor_createmethodinsuper_description,
// new String[]{BasicElementLabels.getJavaElementName(curr.getName()),
// BasicElementLabels.getJavaElementName(binding.getName())});
// resultingCollections.add(new NewDefiningMethodProposal(label, targetCU, astRoot, typeDecl, binding,
// paramNames, 6));
// }
}
}
}
return true;
}
private static boolean getConvertForLoopProposal(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
//TODO
// ForStatement forStatement = getEnclosingForStatementHeader(node);
// if (forStatement == null)
// return false;
//
// if (resultingCollections == null)
// return true;
//
// IProposableFix fix = ConvertLoopFix.createConvertForLoopToEnhancedFix(context.getASTRoot(), forStatement,
// context.getDocument());
// if (fix == null)
// return false;
//
// Images image = Images.correction_change;
// Map<String, String> options = new HashMap<String, String>();
// options.put(CleanUpConstants.CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpOptions.TRUE);
// ICleanUp cleanUp = new ConvertLoopCleanUp(options);
// FixCorrectionProposal proposal = new FixCorrectionProposal(fix, cleanUp, 1, image, context);
// proposal.setCommandId(CONVERT_FOR_LOOP_ID);
//
// resultingCollections.add(proposal);
// return true;
return false;
}
private static boolean getConvertIterableLoopProposal(InvocationContext context, ASTNode node,
Collection<ICommandAccess> resultingCollections) {
//TODO
// ForStatement forStatement = getEnclosingForStatementHeader(node);
// if (forStatement == null)
// return false;
//
// if (resultingCollections == null)
// return true;
//
// IProposableFix fix = ConvertLoopFix.createConvertIterableLoopToEnhancedFix(context.getASTRoot(), forStatement,
// context.getDocument());
// if (fix == null)
// return false;
//
// Images image = Images.correction_change;
// Map<String, String> options = new HashMap<String, String>();
// options.put(CleanUpConstants.CONTROL_STATMENTS_CONVERT_FOR_LOOP_TO_ENHANCED, CleanUpOptions.TRUE);
// ICleanUp cleanUp = new ConvertLoopCleanUp(options);
// FixCorrectionProposal proposal = new FixCorrectionProposal(fix, cleanUp, 1, image, context);
// proposal.setCommandId(CONVERT_FOR_LOOP_ID);
//
// resultingCollections.add(proposal);
// return true;
return false;
}
private static ForStatement getEnclosingForStatementHeader(ASTNode node) {
if (node instanceof ForStatement)
return (ForStatement)node;
while (node != null) {
ASTNode parent = node.getParent();
if (parent instanceof ForStatement) {
StructuralPropertyDescriptor locationInParent = node.getLocationInParent();
if (locationInParent == ForStatement.EXPRESSION_PROPERTY
|| locationInParent == ForStatement.INITIALIZERS_PROPERTY
|| locationInParent == ForStatement.UPDATERS_PROPERTY)
return (ForStatement)parent;
else
return null;
}
node = parent;
}
return null;
}
private static boolean getMakeVariableDeclarationFinalProposals(InvocationContext context,
Collection<ICommandAccess> resultingCollections) {
//TODO final
// SelectionAnalyzer analyzer =
// new SelectionAnalyzer(Selection.createFromStartLength(context.getSelectionOffset(),
// context.getSelectionLength()), false);
// context.getASTRoot().accept(analyzer);
// ASTNode[] selectedNodes = analyzer.getSelectedNodes();
// if (selectedNodes.length == 0)
// return false;
//
// IProposableFix fix = VariableDeclarationFix.createChangeModifierToFinalFix(context.getASTRoot(), selectedNodes);
// if (fix == null)
// return false;
//
// if (resultingCollections == null)
// return true;
//
// Images image = Images.correction_change;
// Map<String, String> options = new HashMap<String, String>();
// options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL, CleanUpOptions.TRUE);
// options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_LOCAL_VARIABLES, CleanUpOptions.TRUE);
// options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PARAMETERS, CleanUpOptions.TRUE);
// options.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL_PRIVATE_FIELDS, CleanUpOptions.TRUE);
// VariableDeclarationCleanUp cleanUp = new VariableDeclarationCleanUp(options);
// FixCorrectionProposal proposal = new FixCorrectionProposal(fix, cleanUp, 5, image, context);
// resultingCollections.add(proposal);
// return true;
return false;
}
private static boolean getInlineLocalProposal(InvocationContext context, final ASTNode node,
Collection<ICommandAccess> proposals) throws CoreException {
//TODO
// if (!(node instanceof SimpleName))
// return false;
//
// SimpleName name = (SimpleName)node;
// IBinding binding = name.resolveBinding();
// if (!(binding instanceof IVariableBinding))
// return false;
// IVariableBinding varBinding = (IVariableBinding)binding;
// if (varBinding.isField() || varBinding.isParameter())
// return false;
// ASTNode decl = context.getASTRoot().findDeclaringNode(varBinding);
// if (!(decl instanceof VariableDeclarationFragment)
// || decl.getLocationInParent() != VariableDeclarationStatement.FRAGMENTS_PROPERTY)
// return false;
//
// if (proposals == null)
// {
// return true;
// }
//
// InlineTempRefactoring refactoring = new InlineTempRefactoring((VariableDeclaration)decl);
// if (refactoring.checkInitialConditions(new NullProgressMonitor()).isOK())
// {
// String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_inline_local_description();
// Images image = Images.correction_change;
// RefactoringCorrectionProposal proposal =
// new RefactoringCorrectionProposal(label, refactoring, 5, context.getDocument(), image);
// proposal.setCommandId(INLINE_LOCAL_ID);
// proposals.add(proposal);
//
// }
// return true;
return false;
}
private static boolean getMissingCaseStatementProposals(InvocationContext context, ASTNode node,
Collection<ICommandAccess> proposals) {
if (node instanceof SwitchCase) {
node = node.getParent();
}
if (!(node instanceof SwitchStatement))
return false;
SwitchStatement switchStatement = (SwitchStatement)node;
ITypeBinding expressionBinding = switchStatement.getExpression().resolveTypeBinding();
if (expressionBinding == null || !expressionBinding.isEnum())
return false;
String[] missingEnumCases =
LocalCorrectionsSubProcessor.evaluateMissingEnumConstantCases(expressionBinding, switchStatement.statements());
if (missingEnumCases.length == 0)
return false;
if (proposals == null)
return true;
proposals.add(LocalCorrectionsSubProcessor.createMissingEnumConstantCaseProposals(context, switchStatement,
missingEnumCases));
return true;
}
private static boolean getConvertLocalToFieldProposal(InvocationContext context, final ASTNode node,
Collection<ICommandAccess> proposals) throws CoreException {
if (!(node instanceof SimpleName))
return false;
SimpleName name = (SimpleName)node;
IBinding binding = name.resolveBinding();
if (!(binding instanceof IVariableBinding)
|| name.getLocationInParent() != VariableDeclarationFragment.NAME_PROPERTY)
return false;
IVariableBinding varBinding = (IVariableBinding)binding;
if (varBinding.isField() || varBinding.isParameter())
return false;
VariableDeclarationFragment decl = (VariableDeclarationFragment)name.getParent();
if (decl.getLocationInParent() != VariableDeclarationStatement.FRAGMENTS_PROPERTY)
return false;
if (proposals == null) {
return true;
}
PromoteTempToFieldRefactoring refactoring = new PromoteTempToFieldRefactoring(decl, context.getDocument());
if (refactoring.checkInitialConditions().isOK()) {
String label = CorrectionMessages.INSTANCE.QuickAssistProcessor_convert_local_to_field_description();
Images image = Images.correction_change;
// LinkedProposalModel linkedProposalModel = new LinkedProposalModel();
// refactoring.setLinkedProposalModel(linkedProposalModel);
RefactoringCorrectionProposal proposal =
new RefactoringCorrectionProposal(label, refactoring, 5, context.getDocument(), image);
// proposal.setLinkedProposalModel(linkedProposalModel);
proposal.setCommandId(CONVERT_LOCAL_TO_FIELD_ID);
proposals.add(proposal);
}
return true;
}
private static class RefactoringCorrectionProposal extends CUCorrectionProposal {
private final Refactoring fRefactoring;
private RefactoringStatus fRefactoringStatus;
public RefactoringCorrectionProposal(String name, Refactoring refactoring, int relevance, Document document,
Images image) {
super(name, null, relevance, document, image);
fRefactoring = refactoring;
}
/**
* Can be overridden by clients to perform expensive initializations of the refactoring
*
* @param refactoring
* the refactoring
* @throws CoreException
* if something goes wrong during init
*/
protected void init(Refactoring refactoring) throws CoreException {
// empty default implementation
}
@Override
protected TextChange createTextChange() throws CoreException {
init(fRefactoring);
fRefactoringStatus = fRefactoring.checkFinalConditions();
if (fRefactoringStatus.hasFatalError()) {
//TODO
// TextFileChange dummyChange = new TextFileChange("fatal error", (IFile)getCompilationUnit().getResource()); //$NON-NLS-1$
// dummyChange.setEdit(new InsertEdit(0, "")); //$NON-NLS-1$
// return dummyChange;
return null;
}
return (TextChange)fRefactoring.createChange();
}
/*
* @see org.eclipse.jdt.internal.ui.text.correction.proposals.CUCorrectionProposal#getAdditionalProposalInfo(org.eclipse.core.runtime.IProgressMonitor)
* @since 3.6
*/
@Override
public Object getAdditionalInfo() {
if (fRefactoringStatus != null && fRefactoringStatus.hasFatalError()) {
return fRefactoringStatus.getEntryWithHighestSeverity().getMessage();
}
return super.getAdditionalInfo();
}
}
}