/******************************************************************************* * Copyright (c) 2009, 2015, 2016 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 * Zend Technologies *******************************************************************************/ package org.eclipse.php.internal.core.codeassist.strategies; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.dltk.core.*; import org.eclipse.dltk.core.search.IDLTKSearchScope; import org.eclipse.dltk.core.search.SearchEngine; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.php.core.codeassist.CompletionCompanion; import org.eclipse.php.core.codeassist.ICompletionContext; import org.eclipse.php.core.codeassist.ICompletionStrategy; import org.eclipse.php.core.codeassist.IElementFilter; import org.eclipse.php.core.compiler.ast.nodes.NamespaceReference; import org.eclipse.php.internal.core.PHPCoreConstants; import org.eclipse.php.internal.core.PHPCorePlugin; import org.eclipse.php.internal.core.codeassist.contexts.AbstractCompletionContext; /** * This strategy contains common utilities of all completion strategies. * * @author michael */ public abstract class AbstractCompletionStrategy implements ICompletionStrategy { private IElementFilter elementFilter; private ICompletionContext context; private CompletionCompanion companion; public AbstractCompletionStrategy(ICompletionContext context) { this.context = context; } public AbstractCompletionStrategy(ICompletionContext context, IElementFilter elementFilter) { this.context = context; this.elementFilter = elementFilter; } public void init(CompletionCompanion companion) { this.companion = companion; } protected CompletionCompanion getCompanion() { return companion; } /** * Return completion context * * @return */ public ICompletionContext getContext() { return context; } public ISourceRange getReplacementRangeWithSpaceAtPrefixEnd(ICompletionContext context) throws BadLocationException { AbstractCompletionContext completionContext = (AbstractCompletionContext) context; int length = completionContext.getPrefix().length(); int start = completionContext.getOffset() - length; int prefixEnd = completionContext.getPrefixEnd(); if (start + length < prefixEnd) { length = prefixEnd - start; } if (completionContext.hasSpaceAtPosition(start + length)) { return new SourceRange(start, length + 1); } return new SourceRange(start, length); } public ISourceRange getReplacementRange(ICompletionContext context) throws BadLocationException { AbstractCompletionContext completionContext = (AbstractCompletionContext) context; int length = completionContext.getPrefix().length(); int start = completionContext.getOffset() - length; int prefixEnd = completionContext.getPrefixEnd(); if (start + length < prefixEnd) { length = prefixEnd - start; } return new SourceRange(start, length); } public String getNSSuffix(ICompletionContext context) { AbstractCompletionContext completionContext = (AbstractCompletionContext) context; String nextWord = null; try { nextWord = completionContext.getNextWord(); } catch (BadLocationException e) { PHPCorePlugin.log(e); } return NamespaceReference.NAMESPACE_DELIMITER.equals(nextWord) ? "" : NamespaceReference.NAMESPACE_DELIMITER; //$NON-NLS-1$ } public ISourceRange getReplacementRangeWithBraces(ICompletionContext context) throws BadLocationException { AbstractCompletionContext completionContext = (AbstractCompletionContext) context; int length = completionContext.getPrefix().length(); int start = completionContext.getOffset() - length; int prefixEnd = completionContext.getPrefixEnd(); if (start + length < prefixEnd) { length = prefixEnd - start; } IDocument document = completionContext.getDocument(); int endOfReplacement = start + length; if (document.getLength() == start) { endOfReplacement = start; } else if (endOfReplacement < document.getLength() - 2) { if (document.getChar(endOfReplacement) == '(' && document.getChar(endOfReplacement + 1) == ')') { endOfReplacement += 2; } } return new SourceRange(start, endOfReplacement - start); } /** * Returns element filter that will be used for filtering out model elements * from proposals list * * @return */ public IElementFilter getElementFilter() { return elementFilter; } /** * Sets element filter that will be used for filtering out model elements * from proposals list * * @param elementFilter */ public void setElementFilter(IElementFilter elementFilter) { this.elementFilter = elementFilter; } /** * Whether code assist should respect case sensitivity * * @return */ protected boolean isCaseSensitive() { return Platform.getPreferencesService().getBoolean(PHPCorePlugin.ID, PHPCoreConstants.CODEASSIST_CASE_SENSITIVITY, false, null); } /** * Filters elements by prefix using case-sensitive comparison * * @param elements * Model elements * @param prefix * String prefix */ protected IModelElement[] filterByCase(IModelElement[] elements, String prefix) { List<IModelElement> result = new ArrayList<IModelElement>(elements.length); for (IModelElement element : elements) { if (element.getElementName().startsWith(prefix)) { result.add(element); } } return (IModelElement[]) result.toArray(new IModelElement[result.size()]); } /** * Creates search scope */ protected IDLTKSearchScope createSearchScope() { ISourceModule sourceModule = ((AbstractCompletionContext) context).getSourceModule(); IScriptProject scriptProject = sourceModule.getScriptProject(); if (scriptProject != null) { return SearchEngine.createSearchScope(scriptProject); } IProjectFragment projectFragment = (IProjectFragment) sourceModule.getAncestor(IModelElement.PROJECT_FRAGMENT); if (projectFragment != null) { return SearchEngine.createSearchScope(projectFragment); } // XXX: add language model here return SearchEngine.createSearchScope(sourceModule); } protected boolean isInsertMode() { IEclipsePreferences preferenceStore = InstanceScope.INSTANCE.getNode(PHPCorePlugin.ID); boolean noOverwrite = preferenceStore.getBoolean(PHPCoreConstants.CODEASSIST_INSERT_COMPLETION, true); return noOverwrite; } }