/******************************************************************************* * Copyright (c) 2017 Alex Xu 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: * Alex Xu - initial API and implementation *******************************************************************************/ package org.eclipse.php.internal.ui.text.correction; import java.util.HashSet; import org.eclipse.dltk.core.*; import org.eclipse.dltk.internal.corext.util.TypeFilter; import org.eclipse.dltk.ui.DLTKUILanguageManager; import org.eclipse.php.core.ast.nodes.Identifier; import org.eclipse.php.core.compiler.PHPFlags; import org.eclipse.php.core.compiler.ast.nodes.NamespaceReference; import org.eclipse.php.internal.core.project.PHPNature; import org.eclipse.php.internal.core.typeinference.FakeConstructor; import org.eclipse.php.internal.core.typeinference.FakeMethod; import org.eclipse.php.internal.core.typeinference.PHPModelUtils; import org.eclipse.php.internal.ui.PHPUiPlugin; public class SimilarElementsRequestor extends CompletionRequestor { public static final int CLASSES = 1 << 1; public static final int INTERFACES = 1 << 2; public static final int REF_TYPES = CLASSES | INTERFACES; public static final int ALL_TYPES = REF_TYPES; public static final String ENCLOSING_TYPE_SEPARATOR = new String( new char[] { NamespaceReference.NAMESPACE_SEPARATOR }); private int fKind; private String fName; private static final TypeFilter filter = new TypeFilter(DLTKUILanguageManager.getLanguageToolkit(PHPNature.ID)); private HashSet<SimilarElement> fResult; public static SimilarElement[] findSimilarElement(ISourceModule cu, Identifier name, int kind) throws ModelException { String identifier = PHPModelUtils.extractElementName(name.getName()); int pos = name.getStart() + 1; SimilarElementsRequestor requestor = new SimilarElementsRequestor(identifier, kind); requestor.setIgnored(CompletionProposal.KEYWORD, true); requestor.setIgnored(CompletionProposal.LABEL_REF, true); requestor.setIgnored(CompletionProposal.PACKAGE_REF, true); requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true); requestor.setIgnored(CompletionProposal.METHOD_REF, true); requestor.setIgnored(CompletionProposal.FIELD_REF, true); requestor.setIgnored(CompletionProposal.LOCAL_VARIABLE_REF, true); requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true); requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true); requestor.setIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION, true); requestor.setIgnored(CompletionProposal.METHOD_NAME_REFERENCE, true); return requestor.process(cu, pos); } /** * Constructor for SimilarElementsRequestor. * * @param name * the name * @param kind * the type kind */ private SimilarElementsRequestor(String name, int kind) { super(); fName = name; fKind = kind; fResult = new HashSet<SimilarElement>(); } private void addResult(SimilarElement elem) { fResult.add(elem); } private SimilarElement[] process(ISourceModule cu, int pos) throws ModelException { try { cu.codeComplete(pos, this, 5000); return fResult.toArray(new SimilarElement[fResult.size()]); } finally { fResult.clear(); } } private boolean isKind(int kind) { return (fKind & kind) != 0; } private static final int getKind(int flags, char[] typeNameSig) { if (Flags.isInterface(flags)) { return INTERFACES; } return CLASSES; } private void addType(char[] typeNameSig, int flags, int relevance) { int kind = getKind(flags, typeNameSig); if (!isKind(kind)) { return; } String fullName = new String(typeNameSig); if (filter.isFiltered(fullName)) { return; } if (NameMatcher.isSimilarName(fName, PHPModelUtils.extractElementName(fullName))) { addResult(new SimilarElement(kind, fullName, relevance)); } } @Override public void accept(CompletionProposal proposal) { if (proposal.getKind() == CompletionProposal.TYPE_REF || proposal.getKind() == CompletionProposal.METHOD_DECLARATION) { String name = null; IModelElement element = proposal.getModelElement(); if (element instanceof IType || element instanceof FakeConstructor) { IMember type = (IMember) element; try { if (!PHPFlags.isNamespace(type.getFlags())) { if (element instanceof FakeConstructor) { element = ((FakeConstructor) element).getParent(); } name = ((IType) element).getTypeQualifiedName(ENCLOSING_TYPE_SEPARATOR); } } catch (ModelException e) { } } else if (element instanceof FakeMethod) { try { name = ((IMethod) element).getTypeQualifiedName(ENCLOSING_TYPE_SEPARATOR, false); } catch (ModelException e) { PHPUiPlugin.log(e); } } if (name != null) { addType(name.toCharArray(), proposal.getFlags(), proposal.getRelevance()); } } } }