/******************************************************************************* * 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.ArrayList; import java.util.List; import org.eclipse.dltk.core.IModelElement; import org.eclipse.php.core.ast.nodes.ASTNode; import org.eclipse.php.core.ast.nodes.IBinding; import org.eclipse.php.core.ast.nodes.Identifier; import org.eclipse.php.core.ast.visitor.AbstractVisitor; /** * Find all nodes connected to a given binding or node. e.g. Declaration of a * field and all references. For types this includes also the constructor * declaration, for methods also overridden methods or methods overriding (if * existing in the same AST), for constructors also the type and all other * constructors. */ public class LinkedNodeFinder { private LinkedNodeFinder() { } /** * Find all nodes connected to the given binding. e.g. Declaration of a * field and all references. For types this includes also the constructor * declaration, for methods also overridden methods or methods overriding * (if existing in the same AST) * * @param root * The root of the AST tree to search * @param binding * The binding of the searched nodes * @return Return */ public static Identifier[] findByBinding(ASTNode root, IBinding binding) { List<Identifier> res = new ArrayList<Identifier>(); BindingFinder nodeFinder = new BindingFinder(binding, res); root.accept(nodeFinder); return res.toArray(new Identifier[res.size()]); } /** * Find all nodes connected to the given name node. If the node has a * binding then all nodes connected to this binding are returned. If the * node has no binding, then all nodes that also miss a binding and have the * same name are returned. * * @param root * The root of the AST tree to search * @param name * The node to find linked nodes for * @return Return */ public static Identifier[] findByNode(ASTNode root, Identifier name) { IBinding binding = name.resolveBinding(); if (binding != null) { return findByBinding(root, binding); } return new Identifier[] { name }; } private static class BindingFinder extends AbstractVisitor { private IModelElement fBinding; private List<Identifier> fResult; public BindingFinder(IBinding binding, List<Identifier> result) { fBinding = getDeclaration(binding); fResult = result; } @Override public boolean visit(Identifier node) { IBinding binding = node.resolveBinding(); if (binding == null || fBinding == null) { return false; } if (fBinding.equals(binding.getPHPElement())) { fResult.add(node); } return false; } private static IModelElement getDeclaration(IBinding binding) { return binding.getPHPElement(); } } }