/******************************************************************************* * Copyright (c) 2009 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.ui.editor.contentassist; import org.eclipse.dltk.core.*; import org.eclipse.dltk.ui.ScriptElementImageDescriptor; import org.eclipse.dltk.ui.ScriptElementImageProvider; import org.eclipse.dltk.ui.text.completion.*; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.viewers.StyledString; import org.eclipse.php.core.PHPVersion; import org.eclipse.php.core.compiler.PHPFlags; import org.eclipse.php.core.compiler.ast.nodes.NamespaceReference; import org.eclipse.php.core.project.ProjectOptions; import org.eclipse.php.internal.core.codeassist.*; import org.eclipse.php.internal.core.project.PHPNature; import org.eclipse.php.internal.core.typeinference.PHPModelUtils; import org.eclipse.php.internal.ui.PHPUiPlugin; import org.eclipse.php.internal.ui.util.PHPPluginImages; import org.eclipse.swt.graphics.Image; public class PHPCompletionProposalCollector extends ScriptCompletionProposalCollector implements IPHPCompletionRequestor { private static final String DOUBLE_COLON = "::";//$NON-NLS-1$ private static final String EMPTY_STRING = "";//$NON-NLS-1$ private IDocument document; private boolean explicit; private int offset; private int flags = CompletionFlag.DEFAULT; public PHPCompletionProposalCollector(IDocument document, ISourceModule cu, boolean explicit) { super(cu); this.document = document; this.explicit = explicit; } @Override protected ScriptCompletionProposal createOverrideCompletionProposal(IScriptProject scriptProject, ISourceModule compilationUnit, String name, String[] paramTypes, int start, int length, String label, String string) { return new PHPOverrideCompletionProposal(scriptProject, compilationUnit, name, paramTypes, start, length, new StyledString(label), string); } protected ScriptCompletionProposal createScriptCompletionProposal(String completion, int replaceStart, int length, Image image, StyledString displayString, int i) { return new PHPCompletionProposal(completion, replaceStart, length, image, displayString, i); } @Override protected ScriptCompletionProposal createScriptCompletionProposal(String completion, int replaceStart, int length, Image image, StyledString displayString, int i, boolean isInDoc) { return new PHPCompletionProposal(completion, replaceStart, length, image, displayString, i, isInDoc); } // protected CompletionProposalLabelProvider createLabelProvider() { // CompletionProposalLabelProvider labelProvider = new // PHPCompletionProposalLabelProvider(); // // // check if there are any adapters extending basic label provider // CompletionProposalLabelProvider extended = // (CompletionProposalLabelProvider) Platform // .getAdapterManager().getAdapter(labelProvider, // CompletionProposalLabelProvider.class); // // if (extended != null) // return extended; // // return labelProvider; // } @Override protected IScriptCompletionProposal createPackageProposal(CompletionProposal proposal) { final AbstractScriptCompletionProposal scriptProposal = (AbstractScriptCompletionProposal) super.createPackageProposal( proposal); final IModelElement modelElement = proposal.getModelElement(); if (modelElement != null) { scriptProposal.setProposalInfo(new ProposalInfo(modelElement.getScriptProject(), proposal.getName())); } return scriptProposal; } @Override protected IScriptCompletionProposal createKeywordProposal(CompletionProposal proposal) { AbstractScriptCompletionProposal scriptProposal = (AbstractScriptCompletionProposal) super.createKeywordProposal( proposal); final IModelElement modelElement = proposal.getModelElement(); if (modelElement != null && modelElement.getElementType() == IModelElement.SOURCE_MODULE) { scriptProposal.setImage(PHPPluginImages.get(PHPPluginImages.IMG_OBJS_PHP_FILE)); } return scriptProposal; } @Override protected IScriptCompletionProposal createScriptCompletionProposal(CompletionProposal proposal) { ScriptCompletionProposal completionProposal; if (proposal.getKind() == CompletionProposal.METHOD_DECLARATION) { completionProposal = createMethodDeclarationProposal(proposal); } else if (proposal.getKind() == CompletionProposal.TYPE_REF) { completionProposal = (ScriptCompletionProposal) createTypeProposal(proposal); } else { completionProposal = (ScriptCompletionProposal) super.createScriptCompletionProposal(proposal); } if (proposal.getKind() == CompletionProposal.METHOD_DECLARATION) { IMethod method = (IMethod) proposal.getModelElement(); try { if (method.isConstructor()) { // replace method icon with class icon: int flags = proposal.getFlags(); ImageDescriptor typeImageDescriptor = ScriptElementImageProvider.getTypeImageDescriptor(flags, false); int adornmentFlags = ScriptElementImageProvider.computeAdornmentFlags(method.getDeclaringType(), ScriptElementImageProvider.SMALL_ICONS | ScriptElementImageProvider.OVERLAY_ICONS); ScriptElementImageDescriptor descriptor = new ScriptElementImageDescriptor(typeImageDescriptor, adornmentFlags, ScriptElementImageProvider.SMALL_SIZE); completionProposal.setImage(getImage(descriptor)); } } catch (ModelException e) { if (DLTKCore.DEBUG_COMPLETION) { e.printStackTrace(); } } } return completionProposal; } @Override protected char[] getVarTrigger() { // variable proposal will be inserted automatically if one of these // characters // is being typed in showing proposal time: return null; } @Override public IDocument getDocument() { return document; } @Override public boolean isExplicit() { return explicit; } private ScriptCompletionProposal createMethodDeclarationProposal(final CompletionProposal proposal) { if (getSourceModule() == null || getSourceModule().getScriptProject() == null) { return null; } String name = proposal.getName(); String completion = proposal.getCompletion(); int replaceStart = proposal.getReplaceStart(); String[] paramTypes; paramTypes = new String[0]; int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = ((PHPCompletionProposalLabelProvider) getLabelProvider()) .createStyledOverrideMethodProposalLabel(proposal); StyledString displayString = ((PHPCompletionProposalLabelProvider) getLabelProvider()) .createStyledMethodProposalLabel(proposal); ScriptCompletionProposal scriptProposal = null; if (ProposalExtraInfo.isNotInsertUse(proposal.getExtraInfo())) { Image image = getImage( ((PHPCompletionProposalLabelProvider) getLabelProvider()).createMethodImageDescriptor(proposal)); scriptProposal = new PHPCompletionProposal(completion, replaceStart, length, image, displayString, 0) { @Override public String getReplacementString() { IMethod method = (IMethod) proposal.getModelElement(); if (ProposalExtraInfo.isNoInsert(proposal.getExtraInfo())) { return method.getElementName(); } setReplacementString(method.getFullyQualifiedName("\\")); //$NON-NLS-1$ return super.getReplacementString(); } @Override public Object getExtraInfo() { return proposal.getExtraInfo(); } }; } else { scriptProposal = createParameterGuessingProposal(proposal, name, paramTypes, start, length, label, completion, proposal.getExtraInfo()); } scriptProposal.setImage(getImage(getLabelProvider().createMethodImageDescriptor(proposal))); ProposalInfo info = new MethodProposalInfo(getSourceModule().getScriptProject(), proposal); scriptProposal.setProposalInfo(info); scriptProposal.setRelevance(computeRelevance(proposal)); return scriptProposal; } private ScriptCompletionProposal createParameterGuessingProposal(CompletionProposal proposal, String name, String[] paramTypes, int start, int length, StyledString label, String string, Object extraInfo) { return new ParameterGuessingProposal(proposal, getSourceModule().getScriptProject(), getSourceModule(), name, paramTypes, start, length, label, string, false, extraInfo, document); } @Override protected IScriptCompletionProposal createTypeProposal(final CompletionProposal typeProposal) { String completion = typeProposal.getCompletion(); int replaceStart = typeProposal.getReplaceStart(); int length = getLength(typeProposal); Image image = getImage( ((PHPCompletionProposalLabelProvider) getLabelProvider()).createTypeImageDescriptor(typeProposal)); StyledString displayString = ((PHPCompletionProposalLabelProvider) getLabelProvider()) .createStyledTypeProposalLabel(typeProposal); ScriptCompletionProposal scriptProposal = new PHPCompletionProposal(completion, replaceStart, length, image, displayString, 0) { private boolean fReplacementStringComputed = false; @Override public String getReplacementString() { if (!fReplacementStringComputed) { String replacementString = computeReplacementString(); if (ProposalExtraInfo.isAddQuote(typeProposal.getExtraInfo())) { replacementString = "'" + replacementString + "'"; //$NON-NLS-1$ //$NON-NLS-2$ } setReplacementString(replacementString); } return super.getReplacementString(); } private String computeReplacementString() { fReplacementStringComputed = true; IType type = (IType) typeProposal.getModelElement(); if (ProposalExtraInfo.isClassInNamespace(typeProposal.getExtraInfo())) { return PHPModelUtils.getFullName(type); // String result = PHPModelUtils.getFullName(type); // if (ProposalExtraInfo.isAddQuote(typeProposal // .getExtraInfo())) { // result = "'" + result + "'"; // } // return result; } String prefix = ""; //$NON-NLS-1$ try { int flags = type.getFlags(); IType currentNamespace = PHPModelUtils.getCurrentNamespaceIfAny(getSourceModule(), getReplacementOffset()); IType namespace = PHPModelUtils.getCurrentNamespace(type); if (!PHPFlags.isNamespace(flags) && namespace == null && currentNamespace != null && !ProjectOptions .getPHPVersion(PHPCompletionProposalCollector.this.getScriptProject().getProject()) .isLessThan(PHPVersion.PHP5_3) && PHPCompletionProposalCollector.this.document .getChar(getReplacementOffset() - 1) != NamespaceReference.NAMESPACE_SEPARATOR) { prefix = prefix + NamespaceReference.NAMESPACE_SEPARATOR; } } catch (ModelException e) { PHPUiPlugin.log(e); } catch (BadLocationException e) { PHPUiPlugin.log(e); } String suffix = getSuffix(type); String replacementString = null; if (typeProposal.getModelElement() instanceof AliasType) { replacementString = ((AliasType) typeProposal.getModelElement()).getAlias(); } else { replacementString = super.getReplacementString(); } return prefix + replacementString + suffix; } public String getSuffix(IType type) { String defaultResult = EMPTY_STRING; if (type instanceof AliasType) { } if (ProposalExtraInfo.isTypeOnly(typeProposal.getExtraInfo()) || !PHPModelUtils.hasStaticOrConstMember(type)) { return defaultResult; } String nextWord = null; try { nextWord = document.get(getReplacementOffset() + getReplacementLength(), 2);// "::".length() } catch (BadLocationException e) { } return DOUBLE_COLON.equals(nextWord) ? defaultResult : DOUBLE_COLON; } @Override public Object getExtraInfo() { return typeProposal.getExtraInfo(); } }; scriptProposal.setRelevance(computeRelevance(typeProposal)); scriptProposal.setProposalInfo(new TypeProposalInfo(getSourceModule().getScriptProject(), typeProposal)); return scriptProposal; } @Override protected IScriptCompletionProposal createFieldProposal(final CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString displayString = ((PHPCompletionProposalLabelProvider) getLabelProvider()) .createStyledFieldProposalLabel(proposal); Image image = getImage( ((PHPCompletionProposalLabelProvider) getLabelProvider()).createFieldImageDescriptor(proposal)); ScriptCompletionProposal scriptProposal = new PHPCompletionProposal(completion, start, length, image, displayString, 0) { private boolean fReplacementStringComputed = false; @Override public String getReplacementString() { if (!fReplacementStringComputed) { String replacementString = computeReplacementString(); if (ProposalExtraInfo.isAddQuote(proposal.getExtraInfo())) { replacementString = "'" + replacementString + "'"; //$NON-NLS-1$ //$NON-NLS-2$ } setReplacementString(replacementString); } fReplacementStringComputed = true; return super.getReplacementString(); } private String computeReplacementString() { IField field = (IField) proposal.getModelElement(); if (field instanceof AliasField) { AliasField aliasField = (AliasField) field; return aliasField.getAlias(); } if (ProposalExtraInfo.isFullName(proposal.getExtraInfo())) { return field.getFullyQualifiedName("\\"); //$NON-NLS-1$ } return super.getReplacementString(); } @Override public Object getExtraInfo() { return proposal.getExtraInfo(); } }; if (getSourceModule().getScriptProject() != null) { scriptProposal.setProposalInfo(new FieldProposalInfo(getSourceModule().getScriptProject(), proposal)); } scriptProposal.setRelevance(computeRelevance(proposal)); scriptProposal.setTriggerCharacters(getVarTrigger()); return scriptProposal; } @Override public int getOffset() { return offset; } @Override public void setOffset(int offset) { this.offset = offset; } @Override protected String getNatureId() { return PHPNature.ID; } @Override public int computeRelevance(CompletionProposal proposal) { // if (ProposalExtraInfo.STUB.equals(proposal.getExtraInfo())) { // return Integer.MAX_VALUE; // } if (proposal.getModelElement() instanceof IMethod && ProposalExtraInfo.isMagicMethod(proposal.getExtraInfo())) { return -1; } if (proposal.getModelElement() instanceof IField && ProposalExtraInfo.isMagicMethod(proposal.getExtraInfo())) { return Integer.MAX_VALUE; } return super.computeRelevance(proposal); } @Override public boolean filter(int flag) { return (flags & flag) != 0; } @Override public void addFlag(int flag) { flags |= flag; } }