/******************************************************************************* * Copyright (c) 2005, 2015 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 * Tom Eicher <eclipse@tom.eicher.name> - [content assist] prefix complete casted method proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=247547 * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. *******************************************************************************/ package org.eclipse.cdt.internal.ui.text.contentassist; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.link.ILinkedModeListener; import org.eclipse.jface.text.link.LinkedModeModel; import org.eclipse.jface.text.link.LinkedModeUI; import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags; import org.eclipse.jface.text.link.LinkedModeUI.IExitPolicy; import org.eclipse.jface.text.link.LinkedPosition; import org.eclipse.jface.text.link.LinkedPositionGroup; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.texteditor.link.EditorLinkedModeUI; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.ui.CUIPlugin; /** * This is a modified version of org.eclipse.jdt.internal.ui.text.java.JavaMethodCompletionProposal * * This class adds a linked mode function compilation proposal with exit policy. */ public class FunctionCompletionProposal extends CCompletionProposal { private boolean fHasParametersComputed; private boolean fHasParameters; protected IParameter[] fFunctionParameters; protected int fInvocationOffset; protected int fParseOffset; protected ITranslationUnit fTranslationUnit; protected IDocument fDocument; public FunctionCompletionProposal(String replacementString, int replacementOffset, int replacementLength, Image image, String displayString, String idString, int relevance, ITextViewer viewer, IFunction function, int invocationOffset, int parseOffset, ITranslationUnit translationUnit, IDocument document) { super(replacementString, replacementOffset, replacementLength, image, displayString, idString, relevance, viewer); fFunctionParameters = function.getParameters(); fInvocationOffset = invocationOffset; fParseOffset = parseOffset; fTranslationUnit = translationUnit; fDocument = document; } @Override public void apply(IDocument document, char trigger, int offset) { if (trigger == ' ' || trigger == '(') trigger = '\0'; super.apply(document, trigger, offset); if (hasParameters()) { setUpLinkedMode(document, ')'); } else if (getReplacementString().endsWith(";")) { //$NON-NLS-1$ setUpLinkedMode(document, ';'); } } /** * Returns {@code true} if the method has any parameters, {@code true} if it has no parameters */ protected final boolean hasParameters() { if (!fHasParametersComputed) { fHasParametersComputed = true; fHasParameters = computeHasParameters(); } return fHasParameters; } private boolean computeHasParameters() { return (fFunctionParameters != null && fFunctionParameters.length != 0); } protected static class ExitPolicy implements IExitPolicy { final char fExitCharacter; public ExitPolicy(char exitCharacter) { fExitCharacter = exitCharacter; } @Override public ExitFlags doExit(LinkedModeModel environment, VerifyEvent event, int offset, int length) { if (event.character == fExitCharacter) { if (environment.anyPositionContains(offset)) { return new ExitFlags(ILinkedModeListener.UPDATE_CARET, false); } else { return new ExitFlags(ILinkedModeListener.UPDATE_CARET, true); } } switch (event.character) { case ';': return new ExitFlags(ILinkedModeListener.NONE, true); default: return null; } } } protected void setUpLinkedMode(IDocument document, char closingCharacter) { if (fTextViewer != null) { int exit = getReplacementOffset() + getReplacementString().length(); try { LinkedPositionGroup group = new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, fInvocationOffset, 0, LinkedPositionGroup.NO_STOP)); LinkedModeModel model = new LinkedModeModel(); model.addGroup(group); model.forceInstall(); LinkedModeUI ui = new EditorLinkedModeUI(model, fTextViewer); ui.setSimpleMode(true); ui.setExitPolicy(new ExitPolicy(closingCharacter)); ui.setExitPosition(fTextViewer, exit, 0, Integer.MAX_VALUE); ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER); ui.enter(); } catch (BadLocationException x) { CUIPlugin.log(x); } } } }