/******************************************************************************* * 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.core.runtime.Assert; import org.eclipse.dltk.core.*; import org.eclipse.dltk.internal.core.ArchiveProjectFragment; import org.eclipse.dltk.ui.DLTKPluginImages; import org.eclipse.dltk.ui.ScriptElementLabels; import org.eclipse.dltk.ui.text.completion.CompletionProposalLabelProvider; import org.eclipse.dltk.ui.text.completion.ICompletionProposalLabelProviderExtension; import org.eclipse.dltk.ui.text.completion.ScriptCompletionProposalCollector; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.StyledString; import org.eclipse.php.core.compiler.IPHPModifiers; import org.eclipse.php.core.compiler.PHPFlags; import org.eclipse.php.core.compiler.ast.nodes.NamespaceReference; import org.eclipse.php.internal.core.codeassist.AliasField; import org.eclipse.php.internal.core.codeassist.AliasMethod; import org.eclipse.php.internal.core.codeassist.AliasType; import org.eclipse.php.internal.core.typeinference.FakeConstructor; import org.eclipse.php.internal.ui.Logger; import org.eclipse.php.internal.ui.PHPUiPlugin; import org.eclipse.php.internal.ui.preferences.PreferenceConstants; import org.eclipse.php.internal.ui.util.PHPModelLabelProvider; import org.eclipse.php.ui.PHPElementLabels; public class PHPCompletionProposalLabelProvider extends CompletionProposalLabelProvider implements ICompletionProposalLabelProviderExtension { private static final PHPModelLabelProvider fLabelProvider = new PHPModelLabelProvider(); private static final String ENCLOSING_TYPE_SEPARATOR = String.valueOf(NamespaceReference.NAMESPACE_SEPARATOR); @Override protected String createMethodProposalLabel(CompletionProposal methodProposal) { return createStyledMethodProposalLabel(methodProposal).toString(); } @Override protected String createOverrideMethodProposalLabel(CompletionProposal methodProposal) { return createStyledOverrideMethodProposalLabel(methodProposal).toString(); } protected StyledString createStyledOverrideMethodProposalLabel(CompletionProposal methodProposal) { StyledString nameBuffer = new StyledString(); IMethod method = (IMethod) methodProposal.getModelElement(); if (method instanceof FakeConstructor && method.getParent() instanceof AliasType) { AliasType aliasType = (AliasType) method.getParent(); nameBuffer.append(aliasType.getAlias()); } else if (method instanceof AliasMethod) { AliasMethod aliasMethod = (AliasMethod) method; nameBuffer.append(aliasMethod.getAlias()); } else { nameBuffer.append(method.getElementName()); } // parameters nameBuffer.append('('); appendStyledParameterList(nameBuffer, methodProposal); nameBuffer.append(')'); // $NON-NLS-1$ appendMethodType(nameBuffer, methodProposal); appendQualifier(nameBuffer, method.getParent()); return nameBuffer; } protected void appendMethodType(StyledString nameBuffer, CompletionProposal methodProposal) { if (showMethodReturnType()) { IMethod method = (IMethod) methodProposal.getModelElement(); if (method instanceof AliasMethod) { method = (IMethod) ((AliasMethod) method).getMethod(); } if (method == null) { return; } try { if (method.isConstructor() || !method.exists()) { return; } nameBuffer.append(getReturnTypeSeparator(), StyledString.DECORATIONS_STYLER); if (PHPFlags.isNullable(method.getFlags())) { nameBuffer.append("?", StyledString.DECORATIONS_STYLER); //$NON-NLS-1$ } String type = method.getType(); if (type == null) { if ((method.getFlags() & IPHPModifiers.AccReturn) != 0) { type = "mixed"; //$NON-NLS-1$ } else { type = "void"; //$NON-NLS-1$ } } nameBuffer.append(type, StyledString.DECORATIONS_STYLER); } catch (ModelException e) { Logger.logException(e); } } } protected void appendFieldType(StyledString nameBuffer, CompletionProposal methodProposal) { IField element = (IField) methodProposal.getModelElement(); if (element instanceof AliasField) { element = (IField) ((AliasField) element).getField(); } if (element == null) { return; } try { if (!element.exists()) { return; } String type = element.getType(); if (type != null) { nameBuffer.append(getReturnTypeSeparator(), StyledString.DECORATIONS_STYLER); nameBuffer.append(type, StyledString.DECORATIONS_STYLER); } } catch (ModelException e) { Logger.logException(e); } } private boolean showMethodReturnType() { return PHPUiPlugin.getDefault().getPreferenceStore() .getBoolean(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE); } @Override public String createTypeProposalLabel(CompletionProposal typeProposal) { return createStyledTypeProposalLabel(typeProposal).toString(); } protected String createLabelWithTypeAndDeclaration(CompletionProposal proposal) { StringBuilder nameBuffer = new StringBuilder(); nameBuffer.append(proposal.getName()); IField field = (IField) proposal.getModelElement(); if (field.getParent() != null) { nameBuffer.append(" - "); //$NON-NLS-1$ IModelElement parent = field.getParent(); nameBuffer.append(parent.getElementName()); } return nameBuffer.toString(); } @Override protected String createTypeProposalLabel(String fullName) { return super.createTypeProposalLabel(fullName); } @Override public ImageDescriptor createImageDescriptor(CompletionProposal proposal) { if (proposal.getModelElement() instanceof ArchiveProjectFragment) { return DLTKPluginImages.DESC_OBJS_JAR; } ImageDescriptor imageDescriptor = fLabelProvider.getImageDescriptor(proposal.getModelElement(), PHPModelLabelProvider.DEFAULT_IMAGEFLAGS); if (imageDescriptor != null) { return imageDescriptor; } return super.createImageDescriptor(proposal); } @Override public ImageDescriptor createTypeImageDescriptor(CompletionProposal proposal) { ImageDescriptor imageDescriptor = fLabelProvider.getImageDescriptor(proposal.getModelElement(), PHPModelLabelProvider.DEFAULT_IMAGEFLAGS); if (imageDescriptor != null) { return imageDescriptor; } return super.createTypeImageDescriptor(proposal); } @Override public String createFieldProposalLabel(CompletionProposal proposal) { return createStyledFieldProposalLabel(proposal).toString(); } @Override public ImageDescriptor createFieldImageDescriptor(CompletionProposal proposal) { ImageDescriptor imageDescriptor = fLabelProvider.getImageDescriptor(proposal.getModelElement(), PHPModelLabelProvider.DEFAULT_IMAGEFLAGS); if (imageDescriptor != null) { return imageDescriptor; } return super.createFieldImageDescriptor(proposal); } @Override public ImageDescriptor createMethodImageDescriptor(CompletionProposal proposal) { ImageDescriptor imageDescriptor = fLabelProvider.getImageDescriptor(proposal.getModelElement(), PHPModelLabelProvider.DEFAULT_IMAGEFLAGS); if (imageDescriptor != null) { return imageDescriptor; } return super.createMethodImageDescriptor(proposal); } @Override public StyledString createStyledFieldProposalLabel(CompletionProposal proposal) { StyledString buffer = new StyledString(); if (proposal.getModelElement() instanceof AliasField) { AliasField aliasField = (AliasField) proposal.getModelElement(); buffer.append(aliasField.getAlias()); } else { buffer.append(proposal.getName()); } IModelElement element = proposal.getModelElement(); if (element != null && element.getElementType() == IModelElement.FIELD) { appendFieldType(buffer, proposal); if (!proposal.getName().startsWith("$")) { //$NON-NLS-1$ appendQualifier(buffer, element.getParent()); } } return buffer; } @Override public StyledString createStyledLabel(CompletionProposal proposal) { switch (proposal.getKind()) { case CompletionProposal.METHOD_NAME_REFERENCE: case CompletionProposal.METHOD_REF: case CompletionProposal.POTENTIAL_METHOD_DECLARATION: return createStyledMethodProposalLabel(proposal); case CompletionProposal.METHOD_DECLARATION: return createStyledOverrideMethodProposalLabel(proposal); case CompletionProposal.TYPE_REF: return createStyledTypeProposalLabel(proposal); case CompletionProposal.FIELD_REF: return createStyledFieldProposalLabel(proposal); case CompletionProposal.LOCAL_VARIABLE_REF: case CompletionProposal.VARIABLE_DECLARATION: return createStyledSimpleLabelWithType(proposal); case CompletionProposal.KEYWORD: return createStyledKeywordLabel(proposal); case CompletionProposal.PACKAGE_REF: case CompletionProposal.LABEL_REF: return createStyledSimpleLabel(proposal); default: Assert.isTrue(false); return null; } } protected StyledString createStyledMethodProposalLabel(CompletionProposal methodProposal) { StyledString nameBuffer = new StyledString(); boolean isAlias = methodProposal.getModelElement() instanceof AliasMethod; // method name if (isAlias) { AliasMethod aliasMethod = (AliasMethod) methodProposal.getModelElement(); nameBuffer.append(aliasMethod.getAlias()); } else { nameBuffer.append(methodProposal.getName()); } // parameters nameBuffer.append('('); appendStyledParameterList(nameBuffer, methodProposal); nameBuffer.append(')'); appendMethodType(nameBuffer, methodProposal); if (isAlias) { return nameBuffer; } IModelElement method = methodProposal.getModelElement(); appendQualifier(nameBuffer, method.getParent()); return nameBuffer; } protected StyledString appendStyledParameterList(StyledString buffer, CompletionProposal methodProposal) { String[] parameterNames = methodProposal.findParameterNames(null); IMethod method = (IMethod) methodProposal.getModelElement(); if (method instanceof AliasMethod) { method = (IMethod) ((AliasMethod) method).getMethod(); } IParameter[] parameters = null; boolean isVariadic = false; try { if (method != null) { parameters = method.getParameters(); if (PHPFlags.isVariadic(method.getFlags())) { isVariadic = true; } } } catch (ModelException e) { Logger.logException(e); } if (parameterNames != null) { final Integer paramLimit = (Integer) methodProposal .getAttribute(ScriptCompletionProposalCollector.ATTR_PARAM_LIMIT); if (paramLimit != null) { for (int i = 0; i < parameterNames.length; i++) { if (i >= paramLimit.intValue()) { break; } if (i > 0) { buffer.append(','); buffer.append(' '); } if (parameters != null && i < parameters.length && PHPFlags.isReference(parameters[i].getFlags())) { buffer.append(PHPElementLabels.REFERENCE_STRING); } if (isVariadic && i + 1 == parameterNames.length) { buffer.append(ScriptElementLabels.ELLIPSIS_STRING); // $NON-NLS-1$ } buffer.append(parameterNames[i]); } return buffer; } } return appendStyledParameterSignature(buffer, parameterNames, parameters, isVariadic); } protected StyledString appendStyledParameterSignature(StyledString buffer, String[] parameterNames, IParameter[] parameters, boolean isVariadic) { if (parameterNames != null) { for (int i = 0; i < parameterNames.length; i++) { if (i > 0) { buffer.append(','); buffer.append(' '); } if (parameters != null && i < parameters.length && PHPFlags.isReference(parameters[i].getFlags())) { buffer.append(PHPElementLabels.REFERENCE_STRING); } if (isVariadic && i + 1 == parameterNames.length) { buffer.append(ScriptElementLabels.ELLIPSIS_STRING); } buffer.append(parameterNames[i]); } } return buffer; } @Override public String createLabel(CompletionProposal proposal) { return createStyledLabel(proposal).toString(); } @Override public StyledString createStyledKeywordLabel(CompletionProposal proposal) { return new StyledString(proposal.getName()); } @Override public StyledString createStyledSimpleLabel(CompletionProposal proposal) { return new StyledString(proposal.getName()); } @Override public StyledString createStyledTypeProposalLabel(CompletionProposal typeProposal) { StyledString nameBuffer = new StyledString(); IType type = (IType) typeProposal.getModelElement(); if (type instanceof AliasType) { AliasType aliasType = (AliasType) type; nameBuffer.append(aliasType.getAlias()); } else { nameBuffer.append(typeProposal.getName()); } boolean isNamespace = false; try { isNamespace = PHPFlags.isNamespace(type.getFlags()); } catch (ModelException e) { Logger.logException(e); } if (!isNamespace) { appendQualifier(nameBuffer, type); if (type.getParent() != null) { nameBuffer.append(" - ", StyledString.DECORATIONS_STYLER); //$NON-NLS-1$ nameBuffer.append(type.getParent().getElementName(), StyledString.QUALIFIER_STYLER); } } return nameBuffer; } @Override public StyledString createStyledSimpleLabelWithType(CompletionProposal proposal) { StyledString buffer = new StyledString(proposal.getName()); IModelElement element = proposal.getModelElement(); if (element != null && element.getElementType() == IModelElement.LOCAL_VARIABLE && element.exists()) { final ILocalVariable var = (ILocalVariable) element; String type = var.getType(); if (type != null) { buffer.append(getReturnTypeSeparator(), StyledString.DECORATIONS_STYLER); buffer.append(type, StyledString.QUALIFIER_STYLER); } } return buffer; } @Override protected String createSimpleLabelWithType(CompletionProposal proposal) { return createStyledSimpleLabelWithType(proposal).toString(); } protected void appendQualifier(StyledString buffer, IModelElement modelElement) { if (modelElement == null) { return; } buffer.append(" - ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ if (modelElement instanceof IType) { IType type = (IType) modelElement; buffer.append(type.getTypeQualifiedName(ENCLOSING_TYPE_SEPARATOR), StyledString.QUALIFIER_STYLER); // $NON-NLS-1$ } else { buffer.append(modelElement.getElementName(), StyledString.QUALIFIER_STYLER); } } }