/******************************************************************************* * Copyright (c) 2013 Zend Technologies 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: * Zend Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.php.internal.core.compiler.ast.parser; import org.eclipse.dltk.ast.statements.Statement; import org.eclipse.php.core.compiler.ast.nodes.FullyQualifiedReference; import org.eclipse.php.core.compiler.ast.nodes.NamespaceReference; import org.eclipse.php.core.compiler.ast.nodes.UsePart; import org.eclipse.php.core.compiler.ast.nodes.UseStatement; import org.eclipse.php.internal.core.typeinference.PHPModelUtils; /** * AST visitor for finding use statements by namespace. * * @author Kaloyan Raev */ public class FindUseStatementByNamespaceASTVisitor extends AbstractUseStatementASTVisitor { /** * Current use statement, used to detect group use statements. */ private UseStatement currentUseStatement; /** * The namespace to look for. */ private String namespace; /** * The found {@link UsePart} node to return as result. */ private UsePart result; @Override protected void visit(UseStatement s) throws Exception { this.currentUseStatement = s; super.visit(s); } @Override public boolean endvisit(Statement s) throws Exception { if (s instanceof UseStatement) { currentUseStatement = null; } return super.endvisit(s); } /** * Constructor of the visitor. * * @param namespace * the namespace to look for * @param offset * the position in the AST tree after which the search stops */ public FindUseStatementByNamespaceASTVisitor(String namespace, int offset) { super(offset); this.namespace = namespace; } /** * Returns the found {@link UsePart} node that corresponds to the specified * namespace. * * @return a <code>UsePart</code> node, or <code>null<code> if there is not * use statement for the specified namespace. */ public UsePart getResult() { return result; } /** * Compares the namespace of the {@link UsePart} node being visited with the * namespace that the visitor is looking for. */ @Override protected boolean visit(UsePart usePart) { String ns = usePart.getNamespace().getFullyQualifiedName(); boolean isGroupStatement = currentUseStatement != null && currentUseStatement.getNamespace() != null; if (isGroupStatement) { String curentFQN = currentUseStatement.getNamespace().getFullyQualifiedName(); ns = PHPModelUtils.concatFullyQualifiedNames(curentFQN, ns); } if (namespace.equalsIgnoreCase(ns)) { if (isGroupStatement) { FullyQualifiedReference fqn = createCombinedFQN(usePart); result = new UsePart(fqn, usePart.getAlias(), Math.max(currentUseStatement.getStatementType(), usePart.getStatementType())); } else { result = usePart; } return false; } return true; } /** * Creates fake FQN hat combines use statement namespace and use part * namespace. * * @param usePart * @return */ private FullyQualifiedReference createCombinedFQN(UsePart usePart) { String firstNamespace = currentUseStatement.getNamespace().getFullyQualifiedName(); String name = PHPModelUtils.extractElementName(usePart.getNamespace().getFullyQualifiedName()); String secondNamespace = PHPModelUtils.extractNameSpaceName(usePart.getNamespace().getFullyQualifiedName()); String fqn = PHPModelUtils.concatFullyQualifiedNames(firstNamespace, secondNamespace); return new FullyQualifiedReference(0, 0, name, new NamespaceReference(0, 0, fqn)); } }