/******************************************************************************* * Copyright (c) 2000, 2012 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 * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.text.correction; import java.util.ArrayList; import java.util.Collection; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.ui.IEditorPart; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.text.ICCompletionProposal; import org.eclipse.cdt.ui.text.IInvocationContext; import org.eclipse.cdt.ui.text.IProblemLocation; import org.eclipse.cdt.ui.text.IQuickAssistProcessor; import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable; import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.text.correction.proposals.LinkedNamesAssistProposal; import org.eclipse.cdt.internal.ui.text.correction.proposals.RenameRefactoringProposal; /** * see org.eclipse.cdt.ui.text.IQuickAssistProcessor */ public class QuickAssistProcessor implements IQuickAssistProcessor { public QuickAssistProcessor() { super(); } @Override public boolean hasAssists(final IInvocationContext context) throws CoreException { IStatus status = ASTProvider.getASTProvider().runOnAST(context.getTranslationUnit(), ASTProvider.WAIT_ACTIVE_ONLY, new NullProgressMonitor(), new ASTRunnable() { @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) throws CoreException { IASTNodeSelector selector= astRoot.getNodeSelector(null); IASTName name= selector.findEnclosingName(context.getSelectionOffset(), context.getSelectionLength()); // Activate the proposal only if a simple name is selected. if (name != null && name == name.getLastName()) { IBinding binding= name.resolveBinding(); if (binding != null) { return Status.OK_STATUS; } } return Status.CANCEL_STATUS; } }); return status.isOK(); } @Override public ICCompletionProposal[] getAssists(final IInvocationContext context, final IProblemLocation[] problemLocations) throws CoreException { final ArrayList<ICCompletionProposal> proposals= new ArrayList<ICCompletionProposal>(); ASTProvider.getASTProvider().runOnAST(context.getTranslationUnit(), ASTProvider.WAIT_ACTIVE_ONLY, new NullProgressMonitor(), new ASTRunnable() { @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) throws CoreException { IASTNodeSelector selector= astRoot.getNodeSelector(null); IASTName name= selector.findEnclosingName(context.getSelectionOffset(), context.getSelectionLength()); // Activate the proposal only if a simple name is selected. if (name != null && name == name.getLastName()) { IBinding binding= name.resolveBinding(); if (binding != null) { boolean noErrorsAtLocation= noErrorsAtLocation(problemLocations); // Quick assists that show up also if there is an error/warning getRenameLocalProposals(context, problemLocations, noErrorsAtLocation, proposals); getRenameRefactoringProposal(context, problemLocations, noErrorsAtLocation, proposals); } } return Status.OK_STATUS; } }); return proposals.isEmpty() ? null : proposals.toArray(new ICCompletionProposal[proposals.size()]); } private boolean noErrorsAtLocation(IProblemLocation[] locations) { if (locations != null) { for (int i= 0; i < locations.length; i++) { if (locations[i].isError()) { return false; } } } return true; } private static void getRenameLocalProposals(IInvocationContext context, IProblemLocation[] locations, boolean noErrorsAtLocation, Collection<ICCompletionProposal> proposals) { LinkedNamesAssistProposal proposal= new LinkedNamesAssistProposal(context.getTranslationUnit()); if (!noErrorsAtLocation) { proposal.setRelevance(1); } proposals.add(proposal); } private static boolean getRenameRefactoringProposal(IInvocationContext context, IProblemLocation[] locations, boolean noErrorsAtLocation, Collection<ICCompletionProposal> proposals) throws CoreException { IEditorPart editor= CUIPlugin.getActivePage().getActiveEditor(); if (!(editor instanceof CEditor)) return false; if (proposals == null) { return true; } RenameRefactoringProposal proposal= new RenameRefactoringProposal((CEditor) editor); if (!noErrorsAtLocation) { proposal.setRelevance(1); } proposals.add(proposal); return true; } }